Я пытаюсь понять новые API-интерфейсы Java 8 Stream.
http://docs.oracle.com/javase/tutorial/collections/streams/reduction.html
Я нашел пример нахождения среднего числа с помощью API сбора. Но я чувствовал, что то же самое можно сделать и с помощью функции reduce().
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) Есть ли какая-то причина, по которой я должен использовать здесь сбор вместо уменьшения?
2) Если я включу все системные выходы отладки, я увижу, что операции, выполняемые между сбором и уменьшением, абсолютно одинаковы. И объединитель вообще не использовался в обоих случаях.
3) Если я делаю потоки параллельными, сбор всегда возвращает мне правильный результат. Метод reduce() каждый раз дает разные результаты.
4) Не следует ли мне использовать метод reduce в параллельных потоках?
Спасибо,
Пол