Java Streams で ` flatMap() ` の後に `filter()` が遅延していないように見えるのはなぜですか?
Java ストリームの flatMap() の後、filter() が「完全に」Lazy ではないのはなぜですか?
Java 8 ストリームでは、次のような中間操作が行われます。 filter() と flatMap() は遅延型です。つまり、findFirst() のような端末操作が呼び出されるまで実行されません。ただし、filter() が flatMap() の後に続く場合、この遅延は完全には実現されず、予期しない動作が発生します。
次のコード例を考えてみましょう:
Stream.of(1, 2, 3) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
出力には、最初の要素が出力され、filter() が遅延し、条件が満たされるとショートサーキットすることを示します。対照的に:
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();
驚くべきことに、すべての要素が出力されます。 filter() は条件をすぐに満たしても、ストリームの後続の要素の処理を続行します。
理由
この動作は、Java Streams の実装によるものです。 flatMap() の後、ストリームには元の要素が含まれなくなります。代わりに、 flatMap() によって生成された一連の平坦化された要素が含まれています。 filter() が続くと、元のストリームではなく、これらのフラット化された要素に対して動作します。
findFirst() で使用される forEachWithCancel() の実装は、シンクが終了するまでスプリッテレータで tryAdvance() を継続的に呼び出します。キャンセルを要求するか、スプリッテレータが使い果たされます。 flatMap() の場合、filter() がすでに一致を見つけた場合でも、スプリッテレータは早期終了の可能性なしに続行します。
修正
この問題は Java 10 で解決され、Java 8 にバックポートされました。この実装では、次のような短絡操作が行われた場合に flatMap() で早期終了できるようになりました。
結論
当然のことながら、filter() が flatMap() の後で遅延していないかのように動作する理由は混乱を招く可能性があります。基礎となる Java Streams 実装によってこの動作が決定され、これは後に Java 10 で対処され、Java 8 にバックポートされました。このようなシナリオを効率的に処理するには、この理解が重要です。
以上がJava Streams で ` flatMap() ` の後に `filter()` が遅延していないように見えるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。
