O Collection.stream (). Filter (). ForEach () é ineficiente comparado a um padrão para cada loop?


15

O IntelliJ IDEA recomendou-me agora mesmo substituir o seguinte loop for-each por uma chamada Java 8 "forEach":

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

A chamada recomendada seria assim:

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

A menos que eu esteja entendendo mal como funciona a funcionalidade subjacente do Stream, parece-me que o uso do stream é uma operação O (2n) em oposição a uma operação O (n) para o padrão para cada loop.


8
Por que você acha que é O ^ 2? De fato, os fluxos foram inventados especificamente para (a) permitir uma sintaxe melhor e (b) não introduzir sobrecarga extra. (Na verdade, eles muitas vezes reduzir a sobrecarga através de avaliação lenta.)
Kilian Foth

Apenas com base na sintaxe, parece que é a primeira iteração para filtrar e, em seguida, iterando sobre os objetos filtrados uma segunda vez para executar meu código.
Mirrana

6
Mesmo assim, isso ainda seria O (2 * N), que é O (N), ou seja, linear e não quadrático. Mas, na verdade, as iterações são intercaladas entre si e ambas podem terminar mais cedo se o resultado já for conhecido - essa é a beleza dos fluxos. Definitivamente vale a pena gastar 15 minutos para ler os fluxos no Java 8; como Venkat Subramaniam escreve: "As expressões Lambda são a droga de porta de entrada para o Java 8, mas o Streams é o verdadeiro vício".
Kilian Foth

1
Além: o loop é um antipattern;)
Thomas Junk

1
@ThomasJunk Você pode explicar como é um antipadrão? Eu não estou familiarizado com este.
Mirrana

Respostas:


21

Os fluxos Java não repetem sua coleção uma vez para cada instrução, apesar do que a sintaxe implica. Aplica a cadeia inteira a cada elemento, um elemento de cada vez.

No seu caso, o fluxo operaria exatamente como o loop. Pegue um elemento, verifique seu predicado e aplique sua operação, depois passe para o próximo elemento.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.