Java 8ストリームfindFirst()とfindAny()

Java 8 Stream findFirst()vs. findAny()

1. 前書き

Java 8Stream APIは、誤解されがちな2つのメソッドfindAny()findFirst()を導入しました。

このクイックチュートリアルでは、これら2つの方法の違いと、それらをいつ使用するかについて説明します。

参考文献:

Javaでオプションのストリームをフィルタリングする

Java 8およびJava 9でオプションのストリームをフィルタリングするための迅速かつ実用的なガイド

Java 8のプリミティブ型ストリーム

プリミティブ型でJava 8ストリームを使用するための迅速かつ実用的なガイド。

Javaでストリーミング可能

この記事では、IterableをStreamに変換する方法と、Iterableインターフェースがそれを直接サポートしない理由について説明します。

2. Stream.findAny()の使用

名前が示すように、findAny()メソッドを使用すると、Streamから任意の要素を見つけることができます。 遭遇順序に注意を払わずに要素を探しているときに使用します。

このメソッドは、Streamが空の場合、空のOptionalインスタンスを返します。

@Test
public void createStream_whenFindAnyResultIsPresent_thenCorrect() {
    List list = Arrays.asList("A","B","C","D");

    Optional result = list.stream().findAny();

    assertTrue(result.isPresent());
    assertThat(result.get(), anyOf(is("A"), is("B"), is("C"), is("D")));
}

非並列操作では、it will most likely return the first element in the Stream but there is no guarantee for this

並列操作を処理する際のパフォーマンスを最大化するには、結果を確実に決定することはできません。

@Test
public void createParallelStream_whenFindAnyResultIsPresent_thenCorrect()() {
    List list = Arrays.asList(1, 2, 3, 4, 5);
    Optional result = list
      .stream().parallel()
      .filter(num -> num < 4).findAny();

    assertTrue(result.isPresent());
    assertThat(result.get(), anyOf(is(1), is(2), is(3)));
}

3. Stream.findFirst()の使用

findFirst()メソッドは、Stream.の最初の要素を検索します。明らかに、このメソッドは、シーケンスの最初の要素が特に必要な場合に使用されます。

遭遇順序がない場合、Streamから要素を返します。 java.util.streamsパッケージのドキュメントには次のように書かれています。

ストリームには、encounter orderが定義されている場合とされていない場合があります。 ソースと中間操作に依存します。

戻り値の型もOptionalインスタンスであり、Streamも空の場合は空になります。

@Test
public void createStream_whenFindFirstResultIsPresent_thenCorrect() {

    List list = Arrays.asList("A", "B", "C", "D");

    Optional result = list.stream().findFirst();

    assertTrue(result.isPresent());
    assertThat(result.get(), is("A"));
}

並列シナリオでは、findFirstメソッドの動作は変わりません。 遭遇順序が存在する場合、常に決定論的に動作します。

4. 結論

このチュートリアルでは、Java 8 Streams APIのfindAny()メソッドとfindFirst()メソッドについて説明しました。 findAny()メソッドはStreamから任意の要素を返し、findFirst()メソッドはStreamの最初の要素を返します。

この記事over on GitHubの完全なソースコードとすべてのコードスニペットを見つけることができます。