Mengapa filter() Selepas flatMap() Tidak Sepenuhnya Malas dalam Java Stream
Dalam Java streams, filter() dianggap malas operasi, bermakna ia tidak dilaksanakan serta-merta, sebaliknya pada titik penggunaan. Walau bagaimanapun, apabila filter() mengikut flatMap(), kelakuannya menyimpang daripada kemalasan sebenar.
Demonstrasi
Pertimbangkan kod berikut:
Stream.of(1, 2, 3) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get();
Dalam contoh ini, penapis() digunakan pada aliran integer. Output menunjukkan bahawa fungsi penapisan hanya digunakan untuk elemen pertama, seperti yang dijangkakan dalam penilaian malas.
1 Result: 1
Walau bagaimanapun, dalam kod berikut:
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();
Penapis( ) digunakan pada aliran yang dijana dengan menggunakan dua operasi flatMap(). Walaupun elemen pertama dalam aliran diratakan memenuhi syarat penapis, fungsi penapisan terus digunakan untuk elemen yang tinggal.
-1 0 1 0 1 2 1 2 3 Result: -1
Penjelasan
Penjelasan sebab bagi tingkah laku ini ialah flatMap() mencipta aliran baharu untuk setiap elemen dalam aliran asal. Walaupun penapis() kekal sebagai operasi malas, operasi meratakan tidak menyokong penamatan awal. Akibatnya, sebaik sahaja proses perataan bermula, ia tidak boleh diganggu, walaupun keadaan penapis dipenuhi kemudian dalam strim.
Implikasi
Tingkah laku ini boleh membawa kepada yang tidak dijangka akibat, terutamanya apabila berhadapan dengan aliran yang tidak terhingga. Sebagai contoh, jika aliran input untuk operasi flatMap() adalah tidak terhingga, operasi penapis() akan cuba menggunakan fungsinya selama-lamanya, walaupun ia dijamin tidak akan menemui elemen yang sepadan.
JDK Fixes
Isu yang diterangkan di sini telah ditangani dalam Java 10 (dan disandarkan ke Java 8). Dalam versi ini, flatMap() telah dioptimumkan untuk menyokong penamatan awal, memastikan bahawa kelakuan penapis() dan operasi malas lain kekal konsisten, tidak kira sama ada mereka mengikuti flatMap().
Atas ialah kandungan terperinci Mengapa Tidak `filter()` Selepas `flatMap()` Sentiasa Malas dalam Strim Java?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!