Apakah Collection.stream (). Filter (). ForEach () tidak efisien dibandingkan dengan standar untuk setiap loop?

15

IntelliJ IDEA merekomendasikan kepada saya saat ini untuk mengganti setiap loop berikut dengan panggilan Java 8 "forEach":

    for (Object o : objects) {
        if (o instanceof SomeObject) {
            doSomething();
        }
    }

Panggilan yang disarankan akan seperti ini:

objects.stream().filter(o -> o instanceof SomeObject).forEach(o -> doSomething());

Kecuali saya salah paham bagaimana fungsi dasar Stream bekerja, bagi saya sepertinya menggunakan stream adalah operasi O (2n) sebagai lawan dari operasi O (n) untuk standar untuk setiap loop.

Mirrana
sumber
8
Menurut Anda mengapa itu O ^ 2? Faktanya, stream diciptakan secara khusus untuk (a) memungkinkan sintaksis yang lebih baik dan (b) tidak memperkenalkan overhead tambahan. (Bahkan, mereka sering mengurangi overhead melalui evaluasi malas.)
Kilian Foth
Hanya berdasarkan pada sintaks, sepertinya iterating pertama kali untuk menyaring dan kemudian iterasi objek yang disaring untuk kedua kalinya untuk menjalankan kode saya.
Mirrana
6
Bahkan jika itu dilakukan itu masih O (2 * N), yaitu O (N), yaitu linier dan tidak kuadratik. Tetapi sebenarnya iterasi saling terkait satu sama lain, dan keduanya dapat berakhir lebih awal jika hasilnya sudah diketahui - itulah keindahan aliran. Pasti bernilai menghabiskan 15 menit untuk membaca tentang aliran di Jawa 8; seperti yang ditulis Venkat Subramaniam, '' Ekspresi Lambda adalah obat gerbang ke Java 8, tetapi Streams adalah kecanduan yang sebenarnya. ''
Kilian Foth
1
Selain: loop Anda adalah antipattern;)
Thomas Junk
1
@ThomasJunk Bisakah Anda menjelaskan bagaimana ini antipattern? Saya tidak terbiasa dengan yang satu ini.
Mirrana

Jawaban:

21

Java stream tidak mengulangi koleksi Anda sekali untuk setiap pernyataan, terlepas dari apa yang tersirat sintaksis. Itu berlaku seluruh rantai untuk setiap elemen, satu elemen pada suatu waktu.

Dalam kasus Anda, aliran akan beroperasi persis seperti loop. Ambil sebuah elemen, periksa terhadap predikat Anda, dan kemudian terapkan operasi Anda, lalu pindah ke elemen berikutnya.

Rosa Richter
sumber