ホームページ > Java > &#&チュートリアル > Java Streams で ` flatMap() ` の後の `filter()` が常に遅延しないのはなぜですか?

Java Streams で ` flatMap() ` の後の `filter()` が常に遅延しないのはなぜですか?

DDD
リリース: 2024-12-11 19:17:13
オリジナル
962 人が閲覧しました

Why Isn't `filter()` After `flatMap()` Always Lazy in Java Streams?

Java ストリームで flatMap() 後の filter() が完全に遅延しない理由

Java ストリームでは、filter() は遅延とみなされますこれは、すぐに実行されるのではなく、消費の時点で実行されることを意味します。ただし、filter() が flatMap() の後に続く場合、その動作は真の怠惰から逸脱します。

デモ

次のコードを考えてみましょう:

Stream.of(1, 2, 3)
        .filter(i -> {
            System.out.println(i);
            return true;
        })
        .findFirst()
        .get();
ログイン後にコピー

この例では、filter() が整数のストリームに適用されます。出力は、遅延評価で予想されるように、フィルター関数が最初の要素に対してのみ呼び出されることを示しています。

1
Result: 1
ログイン後にコピー

ただし、次のコードでは:

Stream.of(1, 2, 3)
        .flatMap(i -> Stream.of(i - 1, i, i + 1))
        .flatMap(i -> Stream.of(i - 1, i, i + 1))
        .filter(i -> {
            System.out.println(i);
            return true;
        })
        .findFirst()
        .get();
ログイン後にコピー

フィルター( ) 関数は、2 つの flatMap() 操作を適用することによって生成されたストリームに適用されます。平坦化されたストリームの最初の要素がフィルター条件を満たしているにもかかわらず、フィルター関数は残りの要素に対して引き続き呼び出されます。

-1
0
1
0
1
2
1
2
3
Result: -1
ログイン後にコピー

説明

この動作の理由は、 flatMap() が元のストリームの要素ごとに新しいストリームを作成するためです。 filter() は遅延操作のままですが、平坦化操作は早期終了をサポートしません。したがって、平坦化プロセスが開始されると、ストリームの後半でフィルター条件が満たされた場合でも、中断することはできません。

影響

この動作により、予期せぬ事態が発生する可能性があります。特に無限ストリームを扱う場合には、その結果が大きくなります。たとえば、 flatMap() オペレーションの入力ストリームが無限の場合、一致する要素が見つからないことが保証されているにもかかわらず、filter() オペレーションはその関数の適用を無期限に試行します。

JDK の修正

ここで説明されている問題は Java 10 で解決されました (および Java 8 にバックポートされました)。これらのバージョンでは、 flatMap() は早期終了をサポートするように最適化されており、 flatMap() に従うかどうかに関係なく、filter() およびその他の遅延操作の動作が一貫したままであることが保証されます。

以上がJava Streams で ` flatMap() ` の後の `filter()` が常に遅延しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート