こんにちは。「Javaを復習する初心者」です。
今回はStream APIのflatMapメソッドを使ってみました。
List<String>に英文が一文ずつ格納されているとします。これを空白で分解することを考えます。
mapメソッド
前回mapメソッドを使いましたので、最初はmapメソッドを使ってみました。
ソース
List<String> lines = new ArrayList<>();
lines.add("The day is done, and the darkness.");
lines.add("Falls from the wing of night.");
lines
.stream()
.map(line -> line.split(" "))
.forEach(element -> System.out.println(Arrays.toString(element)));
上記ではList<String>型変数linesに英文を2つ格納しています。変数linesに対してStream APIを使った操作をしています。
結果
[The, day, is, done,, and, the, darkness.]
[Falls, from, the, wing, of, night.]
実行結果は配列の内容を出力したものになっています。これはforEachメソッド内で、Arrays.toStringメソッドを使ったためです。ストリームの各要素elementが配列ということです。何故このようになるかというと、mapメソッドでline.split(” “)を使ったためで、ストリームの各要素が配列になるからです。
Arrays#stream
次の例はmapメソッド内で、Arrays#streamを使った例です。ストリームの要素lineからArrays.stream(line.split(” “))を生成しています。Arrays#streamは配列からストリームを生成するメソッドです。
ソース
lines
.stream()
.map(line -> Arrays.stream(line.split(" ")))
.forEach(System.out::println);
結果
java.util.stream.ReferencePipeline$Head@e253f1
java.util.stream.ReferencePipeline$Head@1d8d10a
ストリームが2つ出力されました。ストリームの各要素がストリームだからです。
上記のような場合には、flatMapメソッドを使います。以下はmapをflatMapに置き換えたソースと実行結果です。
ソース
lines
.stream()
.flatMap(line -> Arrays.stream(line.split(" ")))
.forEach(System.out::println);
結果
The
day
is
done,
and
the
darkness.
Falls
from
the
wing
of
night.
上記結果では単語が出力されています。flatMapメソッドによって、ひとつのストリームにまとめられます。その結果、ストリームの各要素が文字列になり、forEach文で出力ができます。