1.要素を集める

Streamついに、クラス内で最も興味深いメソッドであるcollect()メソッドに到達しました。これは、ストリームからおなじみのコレクション ( List<T>Set<T>Map<T, R>その他) に移動するために使用されます。

このcollect()メソッドは特別なcollectorオブジェクトを引数として受け取ります。このオブジェクトは、ストリームからすべてのデータを読み取り、それを特定の種類のコレクションに変換して返します。そして、collect メソッド自体がこのコレクションを返します。

これはすべてかなり巧妙な方法で行われます。collectorオブジェクトのタイプは ですCollector<T, A, R>。ご覧のとおり、これには 3 つの型パラメータがあります。最後の型パラメータ ( R) は通常、 のような型ですList<T>。これは、コンパイラがこの型を使用して、collect()メソッド自体の正しい戻り値の型を決定できることを意味します。

あまり混乱しないことを願っています。いずれの場合も、Collector オブジェクトを自分で作成する必要はありません。クラスの静的メソッドによって返される既製のオブジェクトでCollectors十分です。

コレクタークラス

このCollectorsクラスには、あらゆる場面に対応する既製のコレクター オブジェクトを返す静的メソッドがいくつかあります。ここでは最も重要なものについて考えていきます。

toList()
ストリームをリストに変換するオブジェクト ( List<T>)
toSet()
ストリームをセットに変換するオブジェクト ( Set<T>)
toMap()
Map<K, V>ストリームをmap( )に変換するオブジェクト
joining()
ストリームの要素を単一の文字列に連結します。
mapping()
文字列の要素を文字列に変換します。Map<K, V>
groupingBy()
要素をグループ化して返しますMap<K, V>

2. ストリームをリストに変換する

以下は、ストリームを操作し、結果をリストに変換する典型的な例です。

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

List<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toList() );

コレクションからストリームを取得しました。次に、最初の文字が大文字である文字列のみを保持することで、新しいストリームを取得しました。次に、そのストリームからのすべてのデータがコレクションに収集され、返されます。



3. ストリームをセットに変換する

以下は、ストリームを操作し、結果をセットに変換する典型的な例です。

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Set<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toSet() );

すべてはストリームを に変換するコードと非常によく似ていますがList、メソッドによって返される別のコレクター オブジェクトを使用する点が異なりますtoSet()



4. ストリームをマップに変換する

ただし、ストリームをマップに変換するのは少し難しくなります。マップ内の各エントリは、キーと値の 2 つの要素で構成されます。ストリーム内の各要素のキーと値をどのように定義するかを理解する必要があります。

例:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");

Map<String, String> result = list.stream()
   .map( e -> e.split("=") )
   .filter( e -> e.length == 2 )
   .collect( Collectors.toMap(e -> e[0], e -> e[1]) );

ここで何が起こっているのか見てみましょう。

最初の行では、map(...)各文字列を文字列の配列に変換するために使用します。Split メソッドを使用して、各文字列を 2 つの部分に分割します。

filter()2 行目では、ちょうど 2 つの要素を含む配列のみをメソッドに渡します。文字d==3列は 3 つの要素の配列に分割されますが、フィルターに一致しません。

そして最後に、最後の行でストリームを に変換しますMap<String, String>。2 つの関数がメソッドに渡されますtoMap()。ストリームの各要素について、最初の関数は key を返し2 番目の関数は value を返す必要があります。

各配列の最初の要素 (「a」、「b」、「c」) がキーになり、各配列の 2 番目の要素 (「2」、「3」、「4」) が値になります。



5. ストリームを文字列に変換する

別の興味深いコレクター オブジェクトが によって返されますCollectors.joining()。ストリームのすべての要素をString1 つの文字列に変換し、連結します。例

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");
String result = list.stream().collect( Collectors.joining(", ") );