Java 8 Stream findFirst()vs. findAny()
1. 前書き
Java 8Stream APIは、誤解されがちな2つのメソッドfindAny()とfindFirst()を導入しました。
このクイックチュートリアルでは、これら2つの方法の違いと、それらをいつ使用するかについて説明します。
参考文献:
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の完全なソースコードとすべてのコードスニペットを見つけることができます。