LoginSignup
12
14

More than 5 years have passed since last update.

Java に C# の LINQ を移植した

Last updated at Posted at 2016-05-17

Java で LINQ - visGeekCollections

Java 8 がリリースされてラムダ式を書けるようになったのに、いまいち使いづらい Stream API にがっかりしたので C# の LINQ を移植しました。visGeekCollections を使うと C# の LINQ の構文をほとんどそのまま使えるようになります。

ソースコード

GitHub にて公開しています。不具合などがありましたらご連絡ください。
visGeekCollections(GitHub)

LINQ to Object

LINQ を使うと配列、リスト(List<E>)、マップ(Map<K, V>)、セット(Set<E>)などのシーケンシャルなデータの検索や操作を簡単に行うことができます。

従来の書き方
List<Integer> values = new ArrayList<>(); // リストを用意して
for (int val : new int[] { 2, 4, 6, 1, 5, 3 }) { // 数値の配列のうち
    if (val <= 3) { // 3 以下の値を
        values.add(val); // リストに入れて
    }
}
Collections.sort(values); // リストをソートする。
LINQ
List<Integer> values =
        Enumerable.of(2, 4, 6, 1, 5, 3) // 数値の配列のうち
                .where(val -> val <= 3) // 3 以下の値を
                .orderBy(val -> val) // 昇順にソートして
                .toList(); // リストに変換する

使い方

  • 既存のシーケンシャルデータを IEnumerable<T> に変換する。
// 配列
Cat[] catArray = ...;
IEnumerable<String> source = Enumerable.of(catArray);

// List など
List<Cat> catList = ...; // Iterable<T> を継承したオブジェクト
IEnumerable<Cat> source = Enumerable.of(cats);
  • その場で作る
// 可変長引数
IEnumerable<Integer> source = Enumerable.of(1, 2, 3);

// リスト
EnumerableList<Integer> list = new EnumerableList<>(); // extends ArrayList<E> implements IReadOnlyList<T>
EnumerableLinkedList<Integer> linkedList = new EnumerableLinkedList<>(); // extends LinkedList<E> implements IReadOnlyList<T>

// マップ
EnumerableMap<String, Integer> map = new EnumerableMap<>(); // extends HashMap<K, V> implements IReadOnlyMap<T>
EnumerableLinkedMap<String, Integer> linkedMap = new EnumerableLinkedMap<>(); // extends LinkedHashMap<K, V> implements IReadOnlyMap<T>

// セット
EnumerableSet<Integer> set = new EnumerableSet<>(); // extends HashSet<E> implements IReadOnlySet<T>
EnumerableLinkedSet<Integer> linkedSet = new EnumerableLinkedSet<>(); // extends LinkedHashSet<E> implements IReadOnlySet<T>
  • 独自のコレクションクラスを作る
public class CatCollection implements IEnumerable<Cat> {
    private final ArrayList<Cat> cats = new ArrayList<>();

    @Override
    public Iterator<Cat> iterator() {
        return this.cats.iterator();
    }
}

特徴

  • LINQ と同様に遅延実行されます。select() などでは無駄なバッファリングをせず、つど yield する処理になっています。
  • 標準の ListMapSet を置き換えることができる各種コレクションクラスがあります。.NET のクラスと同様に IReadOnly* インターフェイスを実装しています。
  • プリミティブ型、プリミティブ型配列、プリミティブ型のラッパークラスとその配列に対応しています。
  • 集計メソッド(summaxminaverage)は BigDecimal 型に対応しています。
  • Enumerable.of(...) に渡したソースが配列、Collection<T>List<E> である場合、elementAt()count() などの処理がランダムアクセスによって最適化されます。

参考

12
14
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14