Ich versuche, die neuen Java 8 Stream APIs zu verstehen.Suche nach Durchschnitt mit reduzieren und sammeln
http://docs.oracle.com/javase/tutorial/collections/streams/reduction.html
fand ich das Beispiel der Verwendung collect API durchschnittlich Zahlen findet. Aber ich habe das gespürt, das gleiche kann auch mit reduce() gemacht werden.
public class Test {
public static void main(String[] args) {
// Using collect
System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.collect(Averager::new, Averager::accept, Averager::combine)
.average());
// Using reduce
System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.reduce(new Averager(), (t, u) -> {
t.accept(u);
return t;
}, (t, u) -> {
t.combine(u);
return t;
}).average());
}
private static class Averager {
private int total = 0;
private int count = 0;
public Averager() {
// System.out.println("Creating averager");
}
public double average() {
// System.out.println("Finding average");
return count > 0 ? ((double) total)/count : 0;
}
public void accept(int i) {
// System.out.println("Accepting " + i);
total += i;
count++;
}
public void combine(Averager other) {
// System.out.println("Combining the averager : " + other);
total += other.total;
count += other.count;
}
@Override
public String toString() {
return "[total : " + total + ", count: " + count + "]";
}
}
}
1) Gibt es einen Grund, dass ich sammeln statt hier reduzieren sollte?
2) Wenn ich alle Debug-SYSOuts aktivieren, kann ich sehen, dass die ausgeführten Operationen genau dieselben sind, sammeln und reduzieren. Und der Combiner wurde in beiden Fällen überhaupt nicht benutzt.
3) Wenn ich die Streams parallel mache, gibt das Collect immer das korrekte Ergebnis zurück. Die reduce() gibt mir jedes Mal andere Ergebnisse.
4) Sollte ich nicht reduzieren, in parallelen Streams?
Danke,
Paul
Danke für so eine detaillierte Antwort. –
Eine kleine Korrektur: Sammlung ist eigentlich keine Spezialisierung der Reduktion, es ist umgekehrt. Jede Reduktion kann als eine Sammlung ausgedrückt werden, während es keine allgemeine Möglichkeit gibt, eine Sammlung als Reduktion auszudrücken (oder zumindest nicht, ohne den Client-Code zur Verwaltung der Parallelität zu zwingen). In der Tat ist Reduktion eine spezialisierte Form der Sammlung. –