Java - Stream findAny()とfindFirst()の違い

Stream で条件に一致する 1 つの要素を見つけるときは、 findAny()findFirst() API を使うことができます。

findAny() は Stream で最初に探索される要素を返し、 findFirst() は条件に一致する要素の中で Stream で順序が一番前にある要素を返します。

これらの関数の違いについて詳しく見てみましょう。

1. findFirst()

findFirst() は filter 条件に一致する 1 つの要素を Optional として返します。条件に一致する要素がない場合は、emptyが返されます。

List<String> elements = Arrays.asList("a", "a1", "b", "b1", "c", "c1");

Optional<String> firstElement = elements.stream()
        .filter(s -> s.startsWith("b")).findFirst();

System.out.println("findFirst: " + firstElement.get());

Output:

findFirst: b

2. findAny()

findAny()findFirst() のように条件に一致する要素 1 つを返します。

List<String> elements = Arrays.asList("a", "a1", "b", "b1", "c", "c1");

Optional<String> anyElement = elements.stream()
        .filter(s -> s.startsWith("b")).findAny();

System.out.println("findAny: " + anyElement.get());

Output:

findAny: b

3. findFirst() と findAny() の違い

ストリームを直列に処理するとき、 findFirst()findAny() は同じ要素を返し、違いはありません。 ただし、ストリームを並列に処理する場合は違いがあります。

findFirst() は、複数の要素が条件を満たしていても、ストリームの順序を考慮して最も前の要素を返します。

一方、 findAny() は、マルチスレッドでストリームを処理するときに最初に見つかった要素を返します。したがって、ストリームの後ろにある要素が返される可能性があります。

3.1 findFirst() を使った例

以下のコードは、ストリームを並列( parallel())として扱うときに findFirst()を使用する例です。ここで findFirst() は常に b を返します。

List<String> elements = Arrays.asList("a", "a1", "b", "b1", "c", "c1");

Optional<String> firstElement = elements.stream().parallel()
        .filter(s -> s.startsWith("b")).findFirst();

System.out.println("findFirst: " + firstElement.get());

Output:

findFirst: b

3.2 findAny() を使った例

以下のコードは、ストリームを並列に処理するときに findAny() を使用する例です。ここで findAny() は実行するたびに戻り値が変わり、 b1 または b を返します。

List<String> elements = Arrays.asList("a", "a1", "b", "b1", "c", "c1");

Optional<String> anyElement = elements.stream().parallel()
        .filter(s -> s.startsWith("b")).findAny();

System.out.println("findAny: " + anyElement.get());

Output:

findAny: b1

Related Posts

codechachaCopyright ©2019 codechacha