Java
EclipseCollections
JavaDay 11

Eclipse Collectionsのイケてるところイケてないところ

More than 1 year has passed since last update.

Java Advent Calendar 2017 11日目の記事です。

のがみんちょといいます。JavaとAWSの狭間で生きてます。

みなさんEclipse Collectionsはご存知でしょうか。

2004年にGoldman Sachsが開発し、その後OSSとなって2015年にEclipse Foundationに移管されました。

Eclipse Collectionsとは?の内容は、他の資料でまとまっているものがあるため、

イケてるところ、イケてないところにフォーカスしてお伝えします。


Eclipse Collectionsとは?

上記の通り、一般的な内容は、焼き直しになってしまうため割愛します。

下部記載の参考資料を参照してください。


イケてるところ


ファクトリメソッドのAPIが統一的

Java9でもコレクションのファクトリメソッドがリリースされましたが、これはイミュータブルなものです。

Eclipse Collectionsでは、List, Set, Mapなどのコレクションを統一的なAPIで初期化できます。

MutableList<String> list = Lists.mutable.of(); 

MutableSet<String> set = Sets.mutable.of();
MutableMap<String, String> map = Maps.mutable.of();

// ofの代わりにwithも利用可
MutableList<String> list = Lists.mutable.with(); 

// immutableの場合も呼び出し方法はほとんど同じ
ImmutableList<String> list = Lists.immutable.of(); 


多数のデータ構造がある(特にMultimapとPartition)

EclipseCollenctionsでは以下のようなデータ構造をサポートしています。

データ構造
対応するプリミティブ

List

Set

SortedSet
順序つきSet

Bag
重複ありSet

SortedBag
順序つきBag

Map

BiMap
双方向マップ

SortedMap
順序つきMap

Multimap
キーに対応するバリューがコレクション。List, Set, Bagから選択可

Stack

Pair
Tuple形式のデータ


PrimitiveCollection

StreamAPIにも、IntStream, LongStreamなどPrimitiveなStreamはありますが、データ構造としてはList-likeな取扱いしかできません。

前項のコレクション全てに対してPrimitiveなコレクションが存在します。

ラッパークラスを利用するよりも、メモリ効率がよく大量データを処理する場合、顕著に差が出ます。


引数にメソッド参照が利用できるメソッドが存在する

Java8で悩みどころだったのが、Predicateを引数に取るメソッドでは、メソッド参照が利用できませんでした。

Eclipse Collectionsでは、複数メソッドにwithの接尾辞があるものがあり、メソッド参照を有効活用できます。

// Java8での記述

boolean result = this.people.stream().anyMatch(person -> person.hasPet(PetType.CAT));
// Eclipse Collectionsに書き換え
boolean result = this.people.anySatisfy(person -> person.hasPet(PetType.CAT));
// withを用いた場合
boolean result = this.people.anySatisfyWith(Person::hasPet, PetType.CAT);

(参考資料2より引用)


Mapのイテレートが容易

StreamAPIで悩みだったのが、「MapのすべてのValueを変換する」処理が簡潔に書けないものでした。

Eclipse CollectionsのMutableMapには、keyValuesViewというメソッドが存在し、一括での処理が用意になりました。

Maps.mutable.of("Key1", 1, "Key2", 2, "Key3", 3, "Key4", 4)

.keyValuesView() // RichIterable<Pair<String, Integer>>
.collect((k, v) -> Tuples.pair(k, v * 2))// RichIterable<Pair<String, Integer>>
.toMap();


イケてないところ


RichIterable#min、RichIterable#maxが、NoSuchElementExceptionをthrowする

これらはOptionalが開発される前から存在したメソッドです。

空のコレクションでこれらのメソッドを呼び出すと、NoSuchElementExceptionをthrowします。

利用時には空チェックが必須になります。

と書いていたんですが、Eclipse Collections 8.2でRichIterable#minOptional、RichIterable#maxOptionalが追加されていました。

弱点ない・・・?


さいごに

主観で自分がいいなとおもっているものを書きつらねました。

QiitaにもまだEclipse Collectionsの記事は少ないので、利用している方は一緒に布教活動しましょう!


参考資料


  1. https://www.eclipse.org/collections/ja/

  2. http://www.goldmansachs.com/gs-collections/documents/2015-11-28_JJUG_CCC.pdf

  3. http://slides.com/nashcft/jjug_ccc_2017_fall/