lambdaについて調べてみた forEach編 その1
【前提条件】
【List/Set】
まずはList/SetでのforEachを見ていきます。
[List]
public static void main(final String[] args) { final List<String> valueList = new ArrayList<>(); valueList.add("one"); valueList.add("two"); valueList.add("three"); // forEachメソッド valueList.forEach(value -> System.out.println(value)); // 今までのfor文 for (final String value : valueList) { System.out.println(value); } }
forEachの実行結果とfor文の実行結果は同じです。
forEachメソッドはリストが保持している各要素を
ラムダのパラメータとして渡します。
今回のサンプルではvalueListに入っている値が
valueに渡されて、データの数だけ処理が実行されます。
メソッド参照を使うと
valueList.forEach(System.out::println);
で同じように処理が行われます。
[Set]
続いてSetですが、Listと変わりません。
public static void main(final String[] args) { final Set<String> valueSet = new LinkedHashSet<>(); valueSet.add("one"); valueSet.add("two"); valueSet.add("three"); valueSet.forEach(System.out::println); }
【Map】
Mapについてはぱっと思いつくのはSetへの変換です。
public static void main(final String[] args) { final Map<String, Integer> valueMap = new HashMap<>(); valueMap.put("one", 1); valueMap.put("two", 2); valueMap.put("three", 3); valueMap.entrySet().forEach( entry -> System.out.println(entry.getKey() + "-" + entry.getValue())); }
entrySetでMap.EntryクラスのSetを取得。
取得したSetに対してforEachメソッドを呼び出します。
これでも良いのですが、MapインターフェイスにもforEachメソッドが追加されています。
Map#forEachを使えば、Setに変換する必要がありません。
public static void main(final String[] args) { final Map<String, Integer> valueMap = new HashMap<>(); valueMap.put("one", 1); valueMap.put("two", 2); valueMap.put("three", 3); valueMap.forEach((key, value) -> System.out.println(key + "-" + value)); }
これでSetに変換する方法と同じ結果になります。
List/SetのforEachのパラメータはConsumerですが、
MapのforEachはBiConsumerなのでパラメータを2つ受け取っています。
【Array】
public static void main(final String[] args) { final String[] valueArray = { "one", "two", "three" }; Arrays.asList(valueArray).forEach(System.out::println); }
配列は流石にListへ変換しないと無理です。
【for文との違い】
forEachを使うと一時変数の型宣言を省略できて、
for文を書くより簡潔にかけます。
forEachは関数型インターフェイスのオブジェクトを受け取ります。
なので、繰り返しさせる処理を分岐させることができます。
Consumer<String> outputLambda = null; if (isNeedLn) { outputLambda = System.out::println; } else { outputLambda = System.out::print; } valueList.forEach(outputLambda);
関数をオブジェクトを扱うことに慣れていないので、
こういう分岐のさせ方はどうなんだろうかと
思ったりもしますが、できないことはないです。