Javaでのさまざまなタイプのコレクションの組み合わせ
1. 前書き
このクイックチュートリアルでは、Javaでコレクションを組み合わせるさまざまな方法について説明します。
Javaと、Guava、Apacheなどの外部フレームワークを使用したさまざまなアプローチについて説明します。 コレクションの概要については、at this series hereを参照してください。
2. コレクションを操作するための外部ライブラリ
ネイティブアプローチに加えて、外部ライブラリも使用します。 pom.xmlに次の依存関係を追加してください。
org.apache.commons
commons-collections4
4.2
org.apache.commons
commons-exec
1.3
com.google.guava
guava
26.0-jre
最新バージョンは、Maven CentralでCommons、Commons-exec、およびGuavaにあります。
3. Javaでの配列の組み合わせ
3.1. ネイティブJavaソリューション
Javaには、特定のソース配列を宛先配列にコピーする組み込みのvoid arraycopy()メソッドが付属しています。
次の方法で使用できます。
Object[] combined = new Object[first.length + second.length];
System.arraycopy(first, 0, combined, 0, first.length);
System.arraycopy(second, 0, combined, first.length, second.length);
このメソッドでは、配列オブジェクトとともに、コピーする必要がある位置を指定し、長さパラメーターも渡します。
これはネイティブJavaソリューションであるため、外部ライブラリは必要ありません。
3.2. Java 8StreamAPIの使用
ストリームは、いくつかの異なるタイプのコレクションを反復処理する効果的な方法を提供します。 ストリームの使用を開始するには、Java 8 Stream API Tutorialに進んでください。
Streamを使用して配列を組み合わせるには、次のコードを使用できます。
Object[] combined = Stream.concat(Arrays.stream(first), Arrays.stream(second)).toArray();
Stream.concat()は、最初のストリームの要素の後に2番目のストリームの要素が続く連結ストリームを作成します。その後、toArray() メソッドを使用して配列に変換されます。
ストリームを作成するプロセスは、さまざまなタイプのコレクションで同じです。 ただし、さまざまな方法で収集して、さまざまなデータ構造を取得できます。
この方法については、セクション4.2で再検討します。 および5.2。 ListsとSetsで同じ方法を使用する方法を確認します。
3.3. Apache CommonsのArrayUtilsを使用する
Apache Commonsライブラリは、ArrayUtilsパッケージのaddAll()メソッドを提供します。 宛先配列とソース配列をパラメーターとして指定でき、このメソッドは結合された配列を返します。
Object[] combined = ArrayUtils.addAll(first, second);
この方法については、Array Processing with Apache Commons Lang 3の記事でも詳しく説明されています。
3.4. グアバの使用
Guavaは、同じ目的でconcat()メソッドを提供します。
Object [] combined = ObjectArrays.concat(first, second, Object.class);
さまざまなデータ型で使用でき、クラスリテラルと共に2つのソース配列を受け入れて、結合された配列を返します。
4. JavaでListを組み合わせる
4.1. CollectionネイティブaddAll()メソッドの使用
Collectionインターフェース自体は、addAll()メソッドを提供します。このメソッドは、指定されたコレクション内のすべての要素を呼び出し元オブジェクトに追加します。 これについては、this example article:でも詳しく説明されています。
List
このメソッドは、コレクションフレームワークの最も親のインターフェース、つまりCollectionインターフェースで提供されるため、すべてのListsとSetsに適用できます。
4.2. Java 8の使い方
Listsを組み合わせるには、次の方法でStreamとCollectorsを使用できます。
List
これは、セクション3.2のArraysの場合と同じですが、配列に変換する代わりに、コレクターを使用してリストに変換しました。 Collectorsの詳細については、Guide to Java 8’s Collectorsにアクセスしてください。
次のようにflatMapsを使用することもできます。
List
First, we’re using Stream.of() which returns a sequential stream of two lists – first and second. We’ll then pass it to flatMap which will return the contents of a mapped stream after applying the mapping function.この方法は、Merging Streams in Javaの記事でも説明されています。
flatMapの詳細については、this example articleにアクセスしてください。
4.3. Apache CommonsのListUtilsを使用する
CollectionUtils.union は、2つのコレクションの和集合を実行し、すべての要素を含むコレクションを返します。
List
この方法については、A Guide to Apache Commons Collections CollectionUtilsでも説明されています。 詳細については、セクション4.9に進んでください。 この記事の。
4.4. グアバの使用
To merge a List using Guava, we’ll use Iterable which consists of the concat() method.すべてのコレクションを連結した後、次の例に示すように、結合されたListオブジェクトをすばやく取得できます。
Iterable
5. JavaでSetを組み合わせる
5.1. プレーンJavaソリューション
セクション4.1ですでに説明したように、Collectionインターフェースには、ListsとSetsのコピーにも使用できる組み込みのaddAll()メソッドが付属しています。
Set combined = new HashSet<>();
combined.addAll(first);
combined.addAll(second);
5.2. Java 8ストリームの使用
List objectsに使用したのと同じ関数をここで適用できます。
Set combined = Stream
.concat(first.stream(), second.stream())
.collect(Collectors.toSet());
リストと比較した場合の唯一の注目すべき違いは、Collectors.toList()を使用する代わりに、Collectors.toSet()を使用して、提供された2つのストリームのすべての要素を新しいSetに累積することです。
また、Listsと同様に、flatMaps onSetsを使用すると、次のようになります。
Set combined = Stream.of(first, second)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
5.3. Apache Commonsを使用する
ListUtilsと同様に、Set要素の結合を行うSetUtilsを操作することもできます。
Set combined = SetUtils.union(first, second);
5.4. グアバから使用
Guavaライブラリは、JavaでSetsを組み合わせるための簡単なSets.union()メソッドを提供します。
Set combined = Sets.union(first, second);
6. JavaでMapを組み合わせる
6.1. プレーンJavaソリューション
Mapオブジェクトの指定された引数から呼び出し元のMapオブジェクトへのすべてのマッピングをコピーするputAll()メソッドを提供するMapインターフェースを利用できます。 :
Map combined = new HashMap<>();
combined.putAll(first);
combined.putAll(second);
6.2. Java 8の使い方
Since Java 8, the Map class consists of merge() method which accepts a key, value, and a BiFunction.これをJava 8forEachステートメントで使用して、マージ機能を実現できます。
second.forEach((key, value) -> first.merge(key, value, String::concat));
3番目のパラメーター、つまり再マッピング関数は、両方のソースマップに同じキーと値のペアが存在する場合に役立ちます。 この関数は、これらのタイプの値で何をすべきかを指定します。
次のようにflatMapを使用することもできます。
Map combined = Stream.of(first, second)
.map(Map::entrySet)
.flatMap(Collection::stream)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, String::concat));
6.3. Apache CommonsExecの使用
Apache Commons Execは、簡単なmerge(Map<K,V> first, Map<K,V> second)メソッドを提供します。
Map combined = MapUtils.merge(first, second);
6.4. Google Guavaを使用する
GoogleのGuavaライブラリが提供するImmutableMap を使用できます。 putAll()メソッドは、指定されたマップのすべてのキーと値を作成されたマップに関連付けます。
Map combined = ImmutableMap.builder()
.putAll(first)
.putAll(second)
.build();
7. 結論
この記事では、さまざまなタイプのCollectionsを組み合わせるためのさまざまなアプローチについて説明しました。 arrays、Lists、Sets、およびMapsをマージしました。
いつものように、適切な単体テストを含む完全なコードスニペットはover on GitHub.にあります。