talosのプログラミング教室

Java Gold合格への道 ~StreamAPI・merge~

こんにちは。たろすです。

今回はStreamAPIのmergeについて説明します。

使い方

mergeはクセのあるメソッドで、引数のkeyがmapに存在するときとしないときで違う動きをします。

メソッドの定義は以下の通りです。

default V merge(K key,
                V value,
                BiFunction<? super V,? super V,? extends V> remappingFunction)

以下のように使います。

Map<String, String> map = new HashMap<>();
map.put("A", "Java");
map.merge("A", "Script", String::concat);
map.merge("B", "Script", String::concat);
System.out.println(map);
{A=JavaScript, B=Script}

一度目のmergeでは指定されたkey「A」がmapに存在するため、再マッピング関数(String::concat-文字列を結合する)が実行され現在のvalueに引数のvalueを結合した値が再マッピングされます。

一方で、二度目のmergeで指定されたkey「B」はmapに存在しないため、新しくマッピングされます。

その際、再マッピング関数は無視されます。

おわりに

今回はStreamAPIのmergeについて説明しました。

Java Gold合格への道 ~StreamAPI・distinct~

こんにちは。たろすです。

今回はStreamAPIのdistinctについて説明します。

使い方

distinctはストリーム内の重複した要素を排除するメソッドです。

以下のように使います。

int[] array = { 1, 1, 2, 3, 4, 4, 4, 5, 5, 6 };
IntStream stream = Arrays.stream(array);
stream.distinct().forEach(System.out::print);
123456

おわりに

今回はStreamAPIのdistinctについて説明しました。

Java Gold合格への道 ~StreamAPI・flatMap~

こんにちは。たろすです。

今回はStreamAPIのflatMapについて説明します。

使い方

flatMapは入れ子構造のストリームを平坦なストリームに変換するメソッドです。

以下のように使います。

List<List<Integer>> list = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
list.stream().flatMap(Collection::stream).forEach(System.out::print);
123456

「Collection::stream」のところは「n -> n.stream()」とも書けるので覚えておきましょう。

ちなみに平坦化せずに出力すると以下のように表示されます。

[1, 2, 3][4, 5, 6]

おわりに

今回はStreamAPIのflatMapについて説明しました。

Java Gold合格への道 ~StreamAPI・findAny、findFirst~

こんにちは。たろすです。

今回はStreamAPIのfindAny、findFirstについて説明します。

二つとも引数を取らず、Optional型の戻り値を返すメソッドです。

それぞれどのような使い方をするのか見ていきましょう。

findAny

ストリームの要素のうち一つを含むOptionalを返します。

ただし、返される要素は常に同じとは限りません。

ストリームが空の場合は空のOptionalが返されます。

以下のように使います。

int[] array = { 1, 2, 3 };
IntStream stream = Arrays.stream(array);
System.out.println(stream.findAny());
OptionalInt[1]  // 必ず[]の中が1とは限らない

findFirst

ストリームの最初の要素を含むOptionalを返します。

ストリームが空の場合は空のOptionalを返します。

以下のように使います。

int[] array = { 1, 2, 3 };
IntStream stream = Arrays.stream(array);
System.out.println(stream.findFirst());
OptionalInt[1]

おわりに

今回はStreamAPIのfindAny、findFirstについて説明しました。

Java Gold合格への道 ~StreamAPI・anyMatch、allMatch、noneMatch~

こんにちは。たろすです。

今回はStreamAPIのanyMatch、allMatch、noneMatchについて説明します。

三つともPredicateオブジェクトを引数に取り、boolean型の戻り値を返すメソッドです。

それぞれどのような使い方をするのか見ていきましょう。

anyMatch

ストリームの要素のうち一つでも引数のPredicateオブジェクトの評価に当てはまる場合にtrueを返します。

以下のように使います。

int[] array = { 1, 2, 3 };
IntStream stream1 = Arrays.stream(array);
System.out.println(stream1.anyMatch(n -> n == 2));
IntStream stream2 = Arrays.stream(array);
System.out.println(stream2.anyMatch(n -> n == 0));
true
false

allMatch

ストリームの要素すべてが引数のPredicateオブジェクトの評価に当てはまる場合にtrueを返します。

以下のように使います。

int[] array = { 1, 2, 3 };
IntStream stream1 = Arrays.stream(array);
System.out.println(stream1.allMatch(n -> n == 2));
IntStream stream2 = Arrays.stream(array);
System.out.println(stream2.allMatch(n -> n > 0));
false
true

noneMatch

ストリームの要素すべてが引数のPredicateオブジェクトの評価に当てはまらない場合にtrueを返します。

以下のように使います。

IntStream stream1 = Arrays.stream(array);
System.out.println(stream1.noneMatch(n -> n == 2));
IntStream stream2 = Arrays.stream(array);
System.out.println(stream2.noneMatch(n -> n < 0));
false
true

おわりに

今回はStreamAPIのanyMatch、allMatch、noneMatchについて説明しました。

Java Gold合格への道 ~StreamAPI・Streamパイプラインの処理の流れ~

こんにちは。たろすです。

今回はStreamパイプラインの処理の流れについて説明します。

処理の流れを可視化

次のプログラムはどのような出力をすると思いますか?

int[] array = { 1, 2, 3, 4, 5 };
IntStream stream = Arrays.stream(array)
				.filter(n -> n % 2 == 0)
				.peek(System.out::println)
				.filter(n -> n <= 3)
				.peek(System.out::println);
System.out.println("--------------");
stream.count();


答えはこのようになります。

--------------
2
2
4

ちょっと意外に思った方もいるのではないでしょうか。

このような順番で出力されたのにはちゃんと理由があります。


Streamパイプラインの処理の流れは以下のようになっています。

f:id:talosta:20220108120415p:plain

処理は丸数字の順に行われます。

つまり、すべての要素が一度に処理されるわけではなく、一つずつ取り出され逐次に処理されます。

なので、「2」が一つ目のfilterを通ったあとに一つ目のpeekで出力、二つ目のfilterを通ったあとに二つ目のpeekで出力、「4」が一つ目のfilterを通ったあとに一つ目のpeekで出力という順になります。


また、Streamは終端処理が実行されるまで処理は実行されません。

このコードにおける終端処理はcountメソッドなので、countの前にあるsysoutが先に実行されます。

そのため、数字が出力される前に「--------------」が出力されます。

おわりに

今回はStreamパイプラインの処理の流れについて説明しました。

Java Gold合格への道 ~StreamAPI・peek~

こんにちは。たろすです。

今回はStreamAPIのpeekの使い方について説明します。

使い方

peekはStreamオブジェクトをそのまま返すメソッドです。

引数に副作用を伴う処理を書くことで、デバッグに使用することができます。

以下のように使用します。

int[] array = { 1, 2, 3, 4, 5 };
IntStream stream = Arrays.stream(array);
stream.peek(System.out::print).count();
12345

peekメソッドの中で出力する処理を書くことでStreamの中身を可視化できます。

forEachは終端処理なのでそれ以降の処理を行えませんが、peekは中間処理なのでそれ以降に処理を継続できるメリットがあります。

おわりに

今回はStreamAPIのpeekの使い方について説明しました。