Rumah > Java > javaTutorial > Mengapakah `filter()` Nampak Tidak Malas Selepas `flatMap()` dalam Java Streams?

Mengapakah `filter()` Nampak Tidak Malas Selepas `flatMap()` dalam Java Streams?

Susan Sarandon
Lepaskan: 2024-12-23 15:01:10
asal
865 orang telah melayarinya

Why Does `filter()` Seem Non-Lazy After `flatMap()` in Java Streams?

Mengapa filter() tidak "Sepenuhnya" Malas selepas flatMap() dalam Java Streams?

Dalam Java 8 strim, operasi perantaraan seperti filter() dan flatMap() adalah malas, bermakna mereka tidak melaksanakan sehingga operasi terminal seperti findFirst() dipanggil. Walau bagaimanapun, apabila filter() mengikut flatMap(), kemalasan ini tidak disedari sepenuhnya, membawa kepada tingkah laku yang tidak dijangka.

Pertimbangkan contoh kod ini:

Stream.of(1, 2, 3)
        .filter(i -> {
            System.out.println(i);
            return true;
        })
        .findFirst()
        .get();
Salin selepas log masuk

Output menunjukkan bahawa hanya yang pertama elemen dicetak, menunjukkan bahawa penapis() malas dan litar pintas apabila syarat dipenuhi. Sebaliknya:

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();
Salin selepas log masuk

Anehnya, semua elemen dicetak. Walaupun penapis() memenuhi syaratnya serta-merta, ia terus memproses elemen strim berikutnya.

Alasannya

Gelagat ini disebabkan oleh pelaksanaan Java Stream. Selepas flatMap(), strim tidak lagi mengandungi elemen asal. Sebaliknya, ia mengandungi jujukan elemen diratakan yang dihasilkan oleh flatMap(). Apabila penapis() mengikuti, ia beroperasi pada elemen diratakan ini, bukan strim asal.

Pelaksanaan forEachWithCancel(), yang digunakan dalam findFirst(), terus memanggil tryAdvance() pada pembahagi sehingga sinki meminta pembatalan atau pembahagi habis. Dalam kes flatMap(), spliterator terus maju tanpa sebarang kemungkinan penamatan awal, walaupun filter() telah menemui padanan.

Betulkan

Isu ini telah ditangani dalam Java 10 dan backported ke Java 8. Pelaksanaan kini membenarkan penamatan awal dalam flatMap() apabila operasi litar pintas seperti filter() digunakan.

Kesimpulan

Maklumlah, boleh mengelirukan mengapa filter() berkelakuan seolah-olah tidak malas selepas flatMap(). Pelaksanaan Java Streams yang mendasari menentukan tingkah laku ini, yang kemudiannya ditangani dalam Java 10 dan disandarkan kepada Java 8. Pemahaman ini penting untuk mengendalikan senario sedemikian dengan cekap.

Atas ialah kandungan terperinci Mengapakah `filter()` Nampak Tidak Malas Selepas `flatMap()` dalam Java Streams?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan