リスト変換について、for 文を使う場合と Stream map を使う場合で比較していきます。
以下のリストを使います。
stream-map.java
final List<String> months =
Arrays.asList("January", "February", "March", "April", "May", "June", "July", "Augast", "September", "October", "November", "December");
それぞれの要素の一文字目だけで構成されるリストを作ります。
1. for 文を使う
一文字目を格納する空のリストを宣言し、for ループ内で一文字ずつ格納しています。
for.java
final List<String> firstChars = new ArrayList<>();
for (String c : months) {
firstChars.add(c.substring(0,1));
}
for (String fc : firstChars) {
System.out.print(fc);
}
以下のように出力されます。
JFMAMJJASOND
2. forEach 文を使う
関数型に書き換えたものの、空のリストをプログラマ側で用意する必要があります。
forEach.java
final List<String> firstChars = new ArrayList<>();
months.forEach(c -> firstChars.add(c.substring(0,1)));
firstChars.forEach(System.out::print);
3. Stream map() を使う
空のリストを用意するステップはなく、リストから最初の一文字ずつ取り出した結果が、そのまま新しいリストに格納されるように見えます。
Stream の map() メソッドは連続した入力を連続した出力に変換します。
stream-map.java
final List<String> firstChars = months.stream().map(c -> c.substring(0,1)).collect(Collectors.toList());
firstChars3.forEach(System.out::print);
map() メソッドは、入力のリストと出力のリストの要素数が同じになることを保証しますが、データ型については同じになるとは限りません。
もし、各要素の文字数を取得したい場合、文字列型から数値型に変換されて出力されます。
以下は変換後のリストは用意せずに、forEach で要素の内容を直接出力しています。
その程度であれば、1行で記述が可能となります。
stream-map2.java
months.stream().map(c -> c.length()).forEach(cnt -> System.out.print(cnt + " "));
// 7 8 5 5 3 4 4 6 9 7 8 8 と出力される