LoginSignup
16
10

More than 5 years have passed since last update.

Eclipse Collectionsチートシート

Posted at

概要

Eclipse Collections自体の解説については、他に良い記事がたくさんあると思うので、ここでは「〇〇がしたい」と思った時にすぐ参照できるリファレンスとしてアップします。
とりあえず、よく使うものをリストアップしてみましたが、他に出てきたら追加するかもしれません。
※ほとんどList系しか書いてません。

環境

Ver.8.0.0
すみません、普段仕事で使っているバージョンという事で、若干古めです。

pom.xml
        <dependency>
            <groupId>org.eclipse.collections</groupId>
            <artifactId>eclipse-collections-api</artifactId>
            <version>8.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.collections</groupId>
            <artifactId>eclipse-collections</artifactId>
            <version>8.0.0</version>
        </dependency>

初期化

空のリスト

empty
Lists.mutable.empty();

これ以降、特に断りを入れませんが、mutable(MutableList)のほかにimmutable(ImmutableList)も使えます。
ImmutableListは、add等のメソッドが存在せず、変更不可になっています。
※ソート系など、一部MutableListでしか使えないメソッドがありますので、ご注意ください

empty
Lists.immutable.empty();

まとめて初期化

of
Lists.mutable.of(first, second, third);

Iterableを元に初期化

java.util.List等をImmutableList等に変換できます。

ofall
Lists.immutable.ofAll(hogeList);

頻出パターン集

条件を満たす要素だけを取り出す

select
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        assertThat(
                hogeList
                    .select(s -> s.contains("g"))
                    .makeString()
                , is("hoge, fuga")
            );

条件を満たす要素があるかどうか確認したい

anySatisfyは、条件を満たす要素が1つでもあれば、trueを返します。

anySatisfy
        ListIterable<String> hogeList = Lists.mutable.of("hoge", null, "fuga");
        assertThat(
                hogeList.anySatisfy(s -> s == null)
                , is(true)
            );

全ての要素が条件を満たさない事を確認したい

noneSatisfyは、条件を満たす要素が1つもなければ、trueを返します。

noneSatisfy
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        assertThat(
                hogeList.noneSatisfy(s -> s.equals("hogera"))
                , is(true)
            );

1つでも条件を満たす要素があれば取得したい

detectは、条件を満たす要素のうち、最初の1つだけを取り出します。

detect
        ListIterable<String> hogeList = Lists.mutable.of(null, "hoge", "fuga");
        assertThat(
                hogeList.detect(s -> s != null).toString()
                , is("hoge")
            );

要素を変換し、新しいListにする

collect
        ListIterable<String> hogeList = Lists.mutable.of("hogehoge", "fuga", "piyopi");
        assertThat(
                hogeList
                    .collect(s -> s.length())
                    .makeString()
                , is("8, 4, 6")
            );

重複排除

重複を排除し、ユニークな要素のみ残す。

distinct
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo", "fuga", "piyo");
        assertThat(
                hogeList
                    .distinct()
                    .makeString()
                , is("hoge, fuga, piyo")
            );

ユニークと判断する基準を指定する事も可能。この時、結果のリストに残るのは、重複している要素のうち最初の1つのみ。

distinct
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo", "fugafuga", "piyopiyo");
        assertThat(
                hogeList
                    .distinct(HashingStrategies.fromFunction(s -> s.length()))
                    .makeString()
                , is("hoge, fugafuga")
            );

並べ替え

sortThis
        MutableList<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        assertThat(
                hogeList
                    .sortThis()
                    .makeString()
                , is("fuga, hoge, piyo")
            );

並び替えの基準を指定したり、降順にする事も可能。

sortThisBy
        MutableList<String> hogeList = Lists.mutable.of("hogehoge", "fuga", "piyopi");
        assertThat(
                hogeList
                    .sortThisBy(s -> s.length())
                    .reverseThis()
                    .makeString()
                , is("hogehoge, piyopi, fuga")
            );

繰り返し

繰り返し処理をした後、さらに処理を続けて書きたいなら、tapもあるぞ。

each
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        hogeList
            .each(s ->
                System.out.println(s)
            );
        //実行結果
        //hoge
        //fuga
        //piyo

forEachWithIndexなら、index付きでループさせる事ができます。

forEachWithIndex
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        hogeList
            .forEachWithIndex((string, index) ->
                System.out.println(String.valueOf(index).concat(string))
            );
        //実行結果
        //0hoge
        //1fuga
        //2piyo

集計

groupByで、指定した値ごとにグループ化できます。
ListMultimapという型で返ってきて、様々な方法で取り出す事ができるが、私はkeyMultiValuePairsView()メソッドでPair(後述)にして使うのが好きです。

groupBy
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "hogera", "fuga", "fugafuga", "piyo", "piyopiyo");
        hogeList
            .groupBy(s -> s.length())
            .keyMultiValuePairsView()
            .each(p ->{
                System.out.println(p.getOne() + " -> " + p.getTwo());
            });
        //実行結果
        //4 -> [hoge, fuga, piyo]
        //6 -> [hogera]
        //8 -> [fugafuga, piyopiyo]

合計

sumOfInt
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        assertThat(
                hogeList
                    .sumOfInt(s -> s.length())
                , is(12L)
            );

要素を1つだけ取得したい

最初の1つ

要素が1つもない場合は、nullが返される。

getFirst
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        assertThat(
                hogeList
                    .select(s -> s.contains("g"))
                    .getFirst()
                , is("hoge")
            );

最後の1つ

こちらも、要素が1つもない場合は、nullが返される。

getLast
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        assertThat(
                hogeList
                    .select(s -> s.contains("g"))
                    .getLast()
                , is("fuga")
            );

1つしかないはずの要素

select等で要素を1つだけに絞り込めているはずであれば、getOnlyを使おう。
要素が1つでない場合はIllegalStateExceptionが投げられる。

getOnly
        ListIterable<String> hogeList = Lists.mutable.of("hoge", "fuga", "piyo");
        assertThat(
                hogeList
                    .select(s -> s.contains("i"))
                    .getOnly()
                , is("piyo")
            );

標準Collectionからの変換

プロジェクトで使っているフレームワーク等で、java.util.List等の標準Collectionが使われている事はよくあります。
このような場合、Eclipse Collectionsを使いたくなると、下記のように一旦ofAll等でEclipse Collectionsの型に変換する事になりますが、数が多くなってくるとちょい邪魔です。

こんなふうにしがち
List<String> hogeList = Arrays.asList("konna", "fuuni", "shiteita");
ImmutableList<String> fugaList = Lists.immutable.ofAll(hogeList);
fugaList.select(s -> s.length > 4);

こんな時、ListAdapterを使えば一発でeclipse collestionsのメソッドを使えます。
ListでなくArrayなら、ArrayAdapterもあるぞ。

これでよかった
List<String> hogeList = Arrays.asList("kore", "de", "yokatta");
ListAdapter.adapt(hogeList)
           .select(s -> s.length > 4);

あとは、adaptすら不要なListIterateArrayIterateもある。

ListIterate
List<String> hogeList = Arrays.asList("adapt", "mo", "shinai");
ListIterate.select(hogeList, s -> s.length > 4);

その他データセット

2つの値をセットで保持したい

keyとvalueのペアでデータを持ちたい、みたいな時に使う。
Tuplesから、2種類のインスタンスが生成できる。

Pair

それぞれ異なる型の場合はこちら。

Pair
Pair<String, Object> keyValuePair = Tuples.pair("key", value);
String key = keyValuePair.getOne();
Object value = keyValuePair.getTwo();

Twin

同じ型の値を扱う場合は、こちらが使える。

Twin
Twin<String> keyValueTwin = Tuples.twin("key", "valiue");
String key = keyValueTwin.getOne();
String value = keyValueTwin.getTwo();

例外処理

lambdaの中で検査例外が発生してしまったら、せっかく簡潔に書けていたコードが台無しになってしまう。
そんな時は、下記を静的インポートし、throwingメソッドを使う。

import static org.eclipse.collections.impl.block.factory.Procedures.*;
import static org.eclipse.collections.impl.block.factory.Functions.*;
import static org.eclipse.collections.impl.block.factory.Predicates.*;

throwingの中で例外が発生すると、RuntimeExceptionにラップして投げ直してくれる。
これで簡潔に書けるようになった。

throwing
        hogeList
            .each(throwing(Fuga::piyo)
            ;

16
10
0

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
16
10