はじめに
stream()を利用することもよくあると思うけど、最近実際にflatMapメソッドを利用したので、どういうものだろうかと調べてみたので記事にするよ。少し似ているmapメソッドと比較してみるよ。
Stream#map()
mapはstreamの各要素に対して指定の操作を行って返すよ。
公式ドキュメントには以下のように記載されているよ。
このストリームの要素に指定された関数を適用した結果から構成されるストリームを返します。
例えば、map処理で小文字→大文字の処理をしたとすると、イメージは以下のようになるね。
// 処理前 → 処理後
[a, b, c] → [A, B, C]
[[a, b, c], [d, e, f]] → [[A, B, C], [D, E, F]]
実際にコードを書くと以下のようになるよ。
import java.util.List;
public class Main {
public static void main(String[] args) {
final var sample_1 = List.of("a", "b", "c");
final var sample_2 = List.of("d", "e", "f");
final var sampleList = List.of(sample_1, sample_2);
// 結果1
final var map_1 = sample_1.stream().map(String::toUpperCase).toList();
System.out.print(map_1);
// 結果2
final var map_2 = sampleList.stream() //
.map(r -> //
r.stream().map(String::toUpperCase) //
.toList()) //
.toList();
System.out.print(map_2);
// 処理結果
[A, B, C] // 結果1
[[A, B, C], [D, E, F]] // 結果2
ただし、次元は落とせないので、結果を以下のようにしたい場合にflatMapメソッドが使えるよ。
// 処理前 → 処理後
[[a, b, c], [d, e, f]] → [A, B, C, D, E, F]
それでは、flatMapメソッドを見てみよう!
Stream#flatMap()
mapメソッドど同じように各要素に対しての処理を行うことができ、さらにフラット化(配列の次元を1次元落とせる)することができるよ。
公式ドキュメントを見ると以下のように記載されているよ。
このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るストリームを返します。
APIの注:
flatMap()操作には、ストリームの要素に対して1対多の変換を適用した後、結果の要素を新しいストリーム内にフラット化する効果があります。
言葉では難しいので、実際のコードを見せるよ。
import java.util.List;
public class Main {
public static void main(String[] args) {
final var sample_1 = List.of("a", "b", "c");
final var sample_2 = List.of("d", "e", "f");
final var sampleList = List.of(sample_1, sample_2);
// 結果3
final var flatMap = sampleList.stream() //
.flatMap(r -> r.stream() //
.map(String::toUpperCase)) //
.toList();
System.out.print(flatMap);
// 処理結果
[A, B, C, D, E, F]
まとめ
flatMapはよくわからない!って人もこれで使いどころや使い方がわかるはず!
flatMapは少し難しいようにも思うけれど、どういうときに使うか理解して少しずつ慣れていこう。