Java 8 ストリームはいつ消費されたとみなされますか? 質問する

Java 8 ストリームはいつ消費されたとみなされますか? 質問する

私の理解では、Java 8 は、やStreamなどのターミナル操作が実行されると消費されたと見なされます。forEach()count()

multipleFilters_separateただし、以下のテスト ケースでは、遅延中間操作であるIllegalStateExceptionにもかかわらずfilter、2 つのステートメントとして呼び出され、エラーが発生します。それでも、2 つのフィルター操作を 1 つのステートメントに連結して動作させることができます。

@Test(expected=IllegalStateException.class)
public void multipleFilters_separate() {
    Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
    ints.filter(d -> d > 1.3);
    ints.filter(d -> d > 2.3).forEach(System.out::println);
}

@Test
public void multipleFilters_piped() {
    Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
    ints.filter(d -> d > 1.3)
        .filter(d -> d > 2.3)
        .forEach(System.out::println);
}

このことから、Streamそのステートメントがターミナル操作を呼び出すかどうかに関係なく、 はそれを使用する最初のステートメントの後で消費されるものと想定しています。これは正しいでしょうか?

ベストアンサー1

ターミナル操作が実行されると、消費されたとみなされます。ただし、 javadocに記載されているStreamように、複数の中間操作が同じインスタンスに対して実行されることは想定されていません。StreamStream

ストリームは一度だけ操作される(中間または終端ストリーム操作を呼び出す)これにより、たとえば、同じソースが 2 つ以上のパイプラインにフィードされる「フォークされた」ストリームや、同じストリームの複数のトラバーサルが除外されます。ストリーム実装は、ストリームが再利用されていることを検出すると、IllegalStateException をスローすることがあります。ただし、一部のストリーム操作では、新しいストリーム オブジェクトではなくレシーバーが返される場合があるため、すべてのケースで再利用を検出できるとは限りません。

中間ストリーム操作の場合は、Stream前の操作によって返された次の操作を呼び出す必要があります。

public void multipleFilters_separate() {
    Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
    ints = ints.filter(d -> d > 1.3);
    ints.filter(d -> d > 2.3).forEach(System.out::println);
}

おすすめ記事