PCollectionsの概要
1. 概要
この記事では、PCollections、Java library providing persistent, immutable collections.について見ていきます。
Persistent dataの構造(コレクション)は、更新操作中に直接変更することはできません。更新操作の結果を含む新しいオブジェクトが返されます。 それらは不変であるだけでなく永続的でもあります-つまり、after modification is performed, previous versions of the collection remain unchanged.
PCollectionsは、Java Collections frameworkに類似しており、互換性があります。
2. 依存関係
プロジェクトでPCollectionsを使用できるように、pom.xmlに次の依存関係を追加しましょう。
org.pcollections
pcollections
2.1.2
プロジェクトがGradleベースの場合、同じアーティファクトをbuild.gradleファイルに追加できます。
compile 'org.pcollections:pcollections:2.1.2'
最新バージョンはMaven Centralにあります。
3. マップ構造(HashPMap)
HashPMapは、永続的なマップデータ構造です。 これは、null以外のキー値データを格納するために使用されるjava.util.HashMapのアナログです。
HashTreePMap.で便利な静的メソッドを使用してHashPMapをインスタンス化できます。これらの静的メソッドは、IntTreePMap.に基づくHashPMapインスタンスを返します。
HashTreePMapクラスの静的empty()メソッドは、java.util.HashMapのデフォルトコンストラクターを使用するのと同じように、要素を持たない空のHashPMapを作成します。
HashPMap pmap = HashTreePMap.empty();
HashPMapを作成するために使用できる静的メソッドは他に2つあります。 singleton()メソッドは、1つのエントリのみでHashPMapを作成します。
HashPMap pmap1 = HashTreePMap.singleton("key1", "value1");
assertEquals(pmap1.size(), 1);
from()メソッドは、既存のjava.util.HashMapインスタンス(および他のjava.util.Map実装)からHashPMapを作成します。
Map map = new HashMap();
map.put("mkey1", "mval1");
map.put("mkey2", "mval2");
HashPMap pmap2 = HashTreePMap.from(map);
assertEquals(pmap2.size(), 2);
HashPMapはjava.util.AbstractMapとjava.util.Mapからいくつかのメソッドを継承しますが、それに固有のメソッドがあります。
minus()メソッドはマップから単一のエントリを削除し、minusAll()メソッドは複数のエントリを削除します。 それぞれ単一のエントリと複数のエントリを追加するplus()メソッドとplusAll()メソッドもあります。
HashPMap pmap = HashTreePMap.empty();
HashPMap pmap0 = pmap.plus("key1", "value1");
Map map = new HashMap();
map.put("key2", "val2");
map.put("key3", "val3");
HashPMap pmap1 = pmap0.plusAll(map);
HashPMap pmap2 = pmap1.minus("key1");
HashPMap pmap3 = pmap2.minusAll(map.keySet());
assertEquals(pmap0.size(), 1);
assertEquals(pmap1.size(), 3);
assertFalse(pmap2.containsKey("key1"));
assertEquals(pmap3.size(), 0);
pmapでput()を呼び出すとUnsupportedOperationException.がスローされることに注意することが重要です。PCollectionsオブジェクトは永続的で不変であるため、変更操作ごとにオブジェクトの新しいインスタンス(HashPMap)が返されます。 。
次に、他のデータ構造を見てみましょう。
4. リスト構造(TreePVector and ConsPStack)
TreePVectorはjava.util.ArrayListの永続的なアナログであり、ConsPStackはjava.util.LinkedListのアナログです。 TreePVectorとConsPStackには、HashPMapと同様に、新しいインスタンスを作成するための便利な静的メソッドがあります。
empty()メソッドは空のTreePVectorを作成しますが、singleton()メソッドは1つの要素のみでTreePVectorを作成します。 任意のjava.util.CollectionからTreePVectorのインスタンスを作成するために使用できるfrom()メソッドもあります。
ConsPStackには、同じ目標を達成する同じ名前の静的メソッドがあります。
TreePVectorには、それを操作するためのメソッドがあります。 要素を削除するためのminus()メソッドとminusAll()メソッドがあります。 plus()、および要素の追加用のplusAll()。
with()は、指定されたインデックスの要素を置き換えるために使用され、subList()はコレクションから要素の範囲を取得します。
これらのメソッドは、ConsPStackでも使用できます。
上記の方法を例示する次のコードスニペットについて考えてみましょう。
TreePVector pVector = TreePVector.empty();
TreePVector pV1 = pVector.plus("e1");
TreePVector pV2 = pV1.plusAll(Arrays.asList("e2", "e3", "e4"));
assertEquals(1, pV1.size());
assertEquals(4, pV2.size());
TreePVector pV3 = pV2.minus("e1");
TreePVector pV4 = pV3.minusAll(Arrays.asList("e2", "e3", "e4"));
assertEquals(pV3.size(), 3);
assertEquals(pV4.size(), 0);
TreePVector pSub = pV2.subList(0, 2);
assertTrue(pSub.contains("e1") && pSub.contains("e2"));
TreePVector pVW = (TreePVector) pV2.with(0, "e10");
assertEquals(pVW.get(0), "e10");
上記のコードスニペットでは、pSubは別のTreePVectorオブジェクトであり、pV2から独立しています。 観察できるように、pV2はsubList()操作によって変更されませんでした。むしろ、新しいTreePVectorオブジェクトが作成され、インデックス0から2までのpV2の要素で埋められました。
これが不変性の意味であり、PCollectionsのすべての変更メソッドで起こることです。
5. 構造の設定(MapPSet)
MapPSetは、永続的なマップベースのjava.util.HashSetのアナログです。 HashTreePSet –empty()、from()、およびsingleton()の静的メソッドによって便利にインスタンス化できます。 前の例で説明したのと同じように機能します。
MapPSetには、セットデータを操作するためのplus()、plusAll()、minus()、およびminusAll()メソッドがあります。 さらに、java.util.Set、java.util.AbstractCollection、およびjava.util.AbstractSetからメソッドを継承します。
MapPSet pSet = HashTreePSet.empty()
.plusAll(Arrays.asList("e1","e2","e3","e4"));
assertEquals(pSet.size(), 4);
MapPSet pSet1 = pSet.minus("e4");
assertFalse(pSet1.contains("e4"));
最後に、OrderedPSetもあります。これはjava.util.LinkedHashSetと同じように要素の挿入順序を維持します。
6. 結論
結論として、このクイックチュートリアルでは、PCollections(Javaで利用可能なコアコレクションに類似した永続的なデータ構造)を調査しました。 もちろん、PCollectionsJavadocは、ライブラリの複雑さについてより多くの洞察を提供します。
そして、いつものように、完全なコードはover on Githubで見つけることができます。