Collection.stream (). Filter (). ForEach () è inefficiente rispetto a uno standard per ciascun loop?


15

IntelliJ IDEA mi ha consigliato proprio ora di sostituire il seguente ciclo for-each con una chiamata "forEach" Java 8:

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

La chiamata consigliata vorrebbe così:

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

A meno che non fraintenda il funzionamento della funzionalità sottostante di Stream, mi sembra che usare stream sia un'operazione O (2n) anziché un'operazione O (n) per lo standard per ogni ciclo.


8
Perché pensi che sia O ^ 2? In effetti, i flussi sono stati inventati specificamente per (a) consentire una sintassi più piacevole e (b) non introdurre costi aggiuntivi. (In effetti, spesso riducono le spese generali mediante una valutazione pigra.)
Kilian Foth

Basandosi solo sulla sintassi, sembra che prima esegua l'iterazione del filtro e quindi esegua l'iterazione sugli oggetti filtrati una seconda volta per eseguire il mio codice.
Mirrana,

6
Anche se lo facesse, sarebbe comunque O (2 * N), che è O (N), cioè lineare e non quadratico. Ma in realtà le iterazioni sono interlacciate tra loro ed entrambe possono terminare presto se il risultato è già noto - questa è la bellezza dei flussi. Vale sicuramente la pena spendere 15 minuti per leggere gli stream in Java 8; come scrive Venkat Subramaniam, '' Le espressioni lambda sono la droga gateway per Java 8, ma i flussi sono la vera dipendenza ''
Kilian Foth,

1
Inoltre: il tuo loop è un antipasto;)
Thomas Junk

1
@ThomasJunk Puoi spiegare come è un antipattern? Non ho familiarità con questo.
Mirrana,

Risposte:


21

I flussi Java non eseguono l'iterazione della raccolta una volta per ogni istruzione, nonostante ciò che la sintassi implica. Applica l'intera catena a ciascun elemento, un elemento alla volta.

Nel tuo caso, il flusso funzionerebbe esattamente come il ciclo. Prendi un elemento, confrontalo con il tuo predicato, quindi applica l'operazione, quindi passa all'elemento successivo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.