Eclipse Collections 10.0の新機能 - Part 1 #EclipseCollections
本記事はDonald Raab氏による New Features of Eclipse Collections 10.0 — Part 1 - Donald Raab - Medium を元にした日本語版の記事です。日本語でわかりやすい情報となるように適宜編集しており、日本語訳とは違って必ずしも元の文章を訳したものではありません(本人にrewriteの許可をもらっております)。原文を参考にしたい場合は上記リンクからどうぞ。
Eclipse Collections 10.0の新機能を用いたコード例を紹介していきます。
サマリー
本記事では、Eclipse Collections 10.0がリリースされました #EclipseCollections - itohiro73’s blog で挙げた26個の新機能のうち最初の10個を紹介します。
1. MultiReaderList/Bag/Set
に特化したInterface
Eclipse Collectionsには、長らくmulti-reader対応のコレクション実装が存在していましたが、それらに対応するインターフェースは存在していませんでした。10.0以降ではこれらのインターフェースが利用できるようになっています。
@Test public void multiReaderList() { MultiReaderList<String> list = Lists.multiReader.with("1", "2", "3"); list.withWriteLockAndDelegate(backingList -> { Iterator<String> iterator = backingList.iterator(); iterator.next(); iterator.remove(); }); Assert.assertEquals(Lists.mutable.with("2", "3"), list); }
2. プリミティブListからプリミティブStreamを生成する実装
普通のListからStreamを生成するのは簡単ですが、Eclipse Collections 9.xまではプリミティブListからStreamを生成するのは簡単ではありませんでした。10.0からは下記のようにプリミティブListからプリミティブStreamを簡単に生成できます。
@Test public void primitiveListToPrimitiveStream() { IntStream intStream1 = IntLists.mutable.with(1, 2, 3, 4, 5) .primitiveStream(); IntStream intStream2 = IntLists.immutable.with(1, 2, 3, 4, 5) .primitiveStream(); LongStream longStream1 = LongLists.mutable.with(1L, 2L, 3L, 4L, 5L) .primitiveStream(); LongStream longStream2 = LongLists.immutable.with(1L, 2L, 3L, 4L, 5L) .primitiveStream(); DoubleStream doubleStream1 = DoubleLists.mutable.with(1.0, 2.0, 3.0, 4.0, 5.0) .primitiveStream(); DoubleStream doubleStream2 = DoubleLists.immutable.with(1.0, 2.0, 3.0, 4.0, 5.0) .primitiveStream(); }
3. toMap
におけるターゲットMapのサポート
toMap
のオーバーロードとして、ターゲットのMapを引数としてとるメソッドが追加されました。
@Test public void toMapWithTarget() { MutableList<Integer> list = Lists.mutable.with(1, 2, 3, 4, 5); Map<String, Integer> map = list.toMap(String::valueOf, each -> each, new LinkedHashMap<>()); Map<String, Integer> expected = new LinkedHashMap<>(); expected.put("1", 1); expected.put("2", 2); expected.put("3", 3); expected.put("4", 4); expected.put("5", 5); Assert.assertEquals(expected, map); }
4. MutableMapIterable.removeAllKeys
の実装
Mapに対して、あるSetに含まれる要素に対応するキーを削除する removeAllKeys
メソッドが利用できます。
@Test public void removeAllKeys() { MutableMap<Integer, String> map = Maps.mutable.with(1, "1", 2, "2", 3, "3"); map.removeAllKeys(Sets.mutable.with(1, 3)); Assert.assertEquals(Maps.mutable.with(2, "2"), map); }
5 RichIterable.toBiMap
の実装
Eclipse Collections 10.0では、RichIterable
をBiMap
に変換することができます。
@Test public void toBiMap() { MutableBiMap<String, Integer> expected = BiMaps.mutable.with("1", 1, "2", 2, "3", 3); MutableBiMap<String, Integer> biMap = Lists.mutable.with(1, 2, 3).toBiMap(String::valueOf, i -> i); Assert.assertEquals(expected, biMap); }
6 Multimap.collectKeyMultiValues
の実装
Multimapに対して、keyとvalueの両方に対してfunctionを適用して変換できるcollectKeyMultiValues
メソッドが追加になりました。
@Test public void collecKeyMultiValues() { MutableListMultimap<String, String> multimap = Multimaps.mutable.list.with( "nj", "Monmouth", "nj", "Bergen", "nj", "Union"); MutableBagMultimap<String, String> transformed = multimap.collectKeyMultiValues( String::toUpperCase, String::toUpperCase); Assert.assertEquals(Multimaps.mutable.bag.with( "NJ", "MONMOUTH", "NJ", "BERGEN", "NJ", "UNION"), transformed); }
7 コレクションファクトリにおけるfromStream(Stream)
の実装
List
、Set
、Bag
、Stack
のそれぞれのファクトリクラスにおいて、Streamからコレクションを生成するfromStream
メソッドが利用できるようになりました。
@Test public void fromStreamOnCollectionFactories() { MutableList<Integer> list = Lists.mutable.fromStream(Stream.of(1, 2, 3, 4, 5)); Assert.assertEquals( Lists.mutable.with(1, 2, 3, 4, 5), list); MutableSet<Integer> set = Sets.mutable.fromStream(Stream.of(1, 2, 3, 4, 5)); Assert.assertEquals( Sets.mutable.with(1, 2, 3, 4, 5), set); MutableBag<Integer> bag = Bags.mutable.fromStream(Stream.of(1, 2, 3, 4, 5)); Assert.assertEquals( Bags.mutable.with(1, 2, 3, 4, 5), bag); MutableStack<Integer> stack = Stacks.mutable.fromStream(Stream.of(1, 2, 3, 4, 5)); Assert.assertEquals( Stacks.mutable.with(1, 2, 3, 4, 5), stack); }
8 LazyIterate.cartesianProduct
の実装
直積集合を求めるcartesianProduct
メソッドはもともとユーティリティメソッドとして存在していましたが、Set
のみをパラメーターとしてとっていたため、他のIterable
に対してはは明示的にSet
に変換してから呼び出す必要がありました。今回導入された新しい LazyIterate.cartesianProduct
ではどのようなIterable
からも直積集合を求めることができます。
@Test public void cartesianProduct() { MutableList<Integer> numbers = Lists.mutable.with(1, 2, 3); MutableList<String> letters = Lists.mutable.with("A", "B", "C"); MutableList<Pair<String, Integer>> pairs = LazyIterate.cartesianProduct(letters, numbers).toList(); MutableList<Pair<String, Integer>> expected = Lists.mutable.with( Tuples.pair("A", 1), Tuples.pair("A", 2), Tuples.pair("A", 3), Tuples.pair("B", 1), Tuples.pair("B", 2), Tuples.pair("B", 3), Tuples.pair("C", 1), Tuples.pair("C", 2), Tuples.pair("C", 3)); Assert.assertEquals(expected, pairs); }
9 プリミティブMapへのupdateValues
メソッドの追加
プリミティブMapに対して全てのvalueを更新したい場合、 updateValues
を使うことができます。
@Test public void updateValues() { MutableIntIntMap map = IntIntMaps.mutable.empty() .withKeyValue(1, 5) .withKeyValue(2, 3) .withKeyValue(3, 10); map.updateValues((k, v) -> v + 1); MutableIntIntMap expected = IntIntMaps.mutable.empty() .withKeyValue(1, 6) .withKeyValue(2, 4) .withKeyValue(3, 11); Assert.assertEquals(expected, map); }
10 MutableMultimap.getIfAbsentPutAll
の実装
MutableMultimap.getIfAbsentPutAll
は、MutableMap.getIfAbsentPut
と同様の機能を持ちます。違いとしては、MutableMultimap.getIfAbsentPutAll
では複数のvalueをコレクションとしてputすることができる点にあります。
@Test public void getIfAbsentPutAll() { MutableListMultimap<Integer, Integer> multimap = Multimaps.mutable.list.with(2, 1); ImmutableList<Integer> defaultValue = Lists.immutable.with(1, 2, 3); MutableList<Integer> oneValue = multimap.getIfAbsentPutAll(1, defaultValue); MutableList<Integer> twoValue = multimap.getIfAbsentPutAll(2, defaultValue); Assert.assertEquals(defaultValue, oneValue); Assert.assertEquals(Lists.mutable.with(1), twoValue); }
まだまだあります
Eclipse Collections 10.0にはまだ16個の機能が残っています。これらも記事として公開していきますのでお楽しみに。
Eclipse Collections 10.0の新機能、楽しんでいただけると幸いです!!
Eclipse Collectionsはコントリビューションを受け付けています!どこから始めていいかよくわからないという方はitohiro73までDMいただければ喜んでガイドさせていただきます。
もしライブラリを気に入っていただけて、われわれに知らせたいという方は、Twitterでハッシュタグ#EclipseCollectionsをつけてつぶやいていただいたり、もしくはGitHubレポにスターをつけていただけるとめっちゃよろこびますのでどうぞよろしくお願いします!!