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: b2. 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: b3. 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: b3.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: b1Related Posts
- Java - AtomicReference使用方法
 - Java - CountDownLatchを使用する方法、および例
 - Java - ScheduledThreadPoolExecutor使用方法
 - Java - SummaryStatisticsの使用方法(count、min、max、average)
 - Java8 - 関数型インタフェース (Functional Interface) について
 - Java - String配列をint配列に変換する
 - Java - ArrayList要素の値を変更する方法、replaceAll()
 - Java - 2つのリストが同じかどうかを比較
 - Java - 配列から特定のIndex要素を削除する3つの方法
 - Java - HashMapソート、4つの方法
 - Java - 文字列を配列に変換する方法
 - Java - ArrayListが空であることを確認する3つの方法
 - Java - ArrayListの巡回、4つの方法
 - Java - ArrayListの最大値、最小 値を見つける
 - Java - ArrayListの合計、平均値の計算
 - Java - HashMap巡回、3つの方法
 - Java - do whileとwhileの違い
 - Java - Lambda式と関数型インタフェース
 - Java - List empty(null)チェック、3つの方法
 - Java - ArrayListの初期化、4つの方法
 - Java - Stream.reduce()の使い方と例
 - Java - 2つのマップを結合する(merge、putAll)
 - Java - java.util.Dateをjava.sql.Dateに変換する
 - Java - ArrayListをStringに変換する
 - Java - ClassNotFoundExceptionの発生原因と解決策
 - Java - 非静的メソッドは静的コンテキストから参照できません
 - Java - NoSuchMethodErrorの原因と解決策
 - Java - JSONライブラリを使用する方法(JSONObject、JSONArray)
 - Java - byte[]配列をFileに保存
 - Java - byte[]の配列をStringに変換
 - Java - ファイルのアクセス権を確認し、変更
 - Java - 一時フォルダ(Temp directory)パスを取得する
 - Javaでシェルスクリプトを実行
 - Java - Streamを配列に変換する
 - Java - リスト重複排除、2つの方法