Ist Collection.stream (). Filter (). ForEach () im Vergleich zu einem Standard für jede Schleife ineffizient?

14

IntelliJ IDEA hat mir gerade empfohlen, die folgende for-each-Schleife durch einen Java 8 "forEach" -Aufruf zu ersetzen:

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

Der empfohlene Anruf würde so aussehen:

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

Sofern ich nicht falsch verstehe, wie die zugrunde liegende Funktionalität von Stream funktioniert, scheint mir die Verwendung von Stream eine O (2n) -Operation im Gegensatz zu einer O (n) -Operation für den Standard für jede Schleife zu sein.

agent154
quelle
8
Warum denkst du, ist es O ^ 2? Tatsächlich wurden Streams speziell erfunden, um (a) eine schönere Syntax zu ermöglichen und (b) keinen zusätzlichen Overhead einzuführen. (Tatsächlich reduzieren sie häufig den Overhead durch verzögerte Auswertung.)
Kilian Foth,
Nur basierend auf der Syntax sieht es so aus, als würde zuerst gefiltert und dann ein zweites Mal über die gefilterten Objekte iteriert, um meinen Code auszuführen.
agent154
6
Selbst wenn es so wäre, wäre das immer noch O (2 * N), was O (N) ist, dh linear und nicht quadratisch. Tatsächlich sind die Iterationen jedoch miteinander verschachtelt, und beide werden möglicherweise vorzeitig beendet, wenn das Ergebnis bereits bekannt ist - das ist das Schöne an Streams. Es lohnt sich auf jeden Fall, 15 Minuten zu verbringen, um die Streams in Java 8 zu lesen. wie Venkat Subramaniam schreibt: "Lambda-Ausdrücke sind das Tor zu Java 8, aber Streams sind die wahre Sucht."
Kilian Foth
1
Außerdem: Ihre Schleife ist ein Gegenmuster;)
Thomas Junk
1
@ThomasJunk Kannst du erklären, wie es ein Antimuster ist? Ich kenne mich damit nicht aus.
agent154

Antworten:

20

Java-Streams durchlaufen Ihre Sammlung nicht einmal für jede Anweisung, unabhängig davon, was die Syntax impliziert. Es wird die gesamte Kette auf jedes Element angewendet, jeweils ein Element.

In Ihrem Fall würde der Stream genau wie die Schleife funktionieren. Nehmen Sie ein Element, vergleichen Sie es mit Ihrem Prädikat, wenden Sie dann Ihre Operation an und fahren Sie mit dem nächsten Element fort.

Rosa Richter
quelle