Collection.stream (). Filter (). ForEach () est-il inefficace par rapport à un standard pour chaque boucle?

15

IntelliJ IDEA m'a recommandé de remplacer la boucle for-each suivante par un appel Java 8 "forEach":

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

L'appel recommandé aimerait ceci:

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

À moins que je ne comprenne mal comment fonctionne la fonctionnalité sous-jacente de Stream, il me semble que l'utilisation de stream est une opération O (2n) par opposition à une opération O (n) pour la boucle standard pour chaque boucle.

Mirrana
la source
8
Pourquoi pensez-vous que c'est O ^ 2? En fait, les flux ont été inventés spécifiquement pour (a) permettre une meilleure syntaxe et (b) ne pas introduire de surcharge supplémentaire. (En fait, ils réduisent souvent les frais généraux via une évaluation paresseuse.)
Kilian Foth
Juste basé sur la syntaxe, il semble que ce soit une première itération pour filtrer puis une itération sur les objets filtrés une deuxième fois pour exécuter mon code.
Mirrana
6
Même s'il le faisait, ce serait toujours O (2 * N), qui est O (N), c'est-à-dire linéaire et non quadratique. Mais en réalité, les itérations sont entrelacées les unes avec les autres, et les deux peuvent se terminer tôt si le résultat est déjà connu - c'est la beauté des flux. Cela vaut vraiment la peine de passer 15 minutes pour lire les flux de Java 8; comme l'écrit Venkat Subramaniam, '' les expressions Lambda sont la drogue de passerelle vers Java 8, mais les Streams sont la véritable dépendance. ''
Kilian Foth
1
D'ailleurs: votre boucle est un contre-modèle;)
Thomas Junk
1
@ThomasJunk Pouvez-vous expliquer en quoi c'est un contre-modèle? Je ne connais pas celui-ci.
Mirrana

Réponses:

21

Les flux Java n'itèrent pas une fois dans votre collection pour chaque instruction, malgré ce que la syntaxe implique. Il applique la chaîne entière à chaque élément, un élément à la fois.

Dans votre cas, le flux fonctionnerait exactement comme la boucle. Prenez un élément, comparez-le à votre prédicat, puis appliquez votre opération, puis passez à l'élément suivant.

Rosa Richter
la source