Multiple traversals
Brian Goetz
brian.goetz at oracle.com
Fri Dec 20 12:36:35 PST 2013
If the goal is simply to compute min/max at the same time (or any two
reductions), then Collector already gives you an easy way to do that:
IntSummaryStatistics ss = list.blah(...).barg(...)
.collect(summarizingInt());
// or IntStream.summaryStatistics();
This computes sum, min, max, count in one pass. Of course, you can
adapt this pattern to compute anything you want. The code is trivial:
public static <T>
Collector<T, ?, IntSummaryStatistics>
summarizingInt(ToIntFunction<? super T> mapper) {
return new CollectorImpl<T, IntSummaryStatistics,
IntSummaryStatistics>(
IntSummaryStatistics::new,
(r, t) -> r.accept(mapper.applyAsInt(t)),
(l, r) -> { l.combine(r); return l; }, CH_ID);
}
where
public class IntSummaryStatistics implements IntConsumer {
private long count;
private long sum;
private int min = Integer.MAX_VALUE;
private int max = Integer.MIN_VALUE;
/**
* Construct an empty instance with zero count, zero sum,
* {@code Integer.MAX_VALUE} min, {@code Integer.MIN_VALUE} max and
zero
* average.
*/
public IntSummaryStatistics() { }
/**
* Records a new value into the summary information
*
* @param value the input value
*/
@Override
public void accept(int value) {
++count;
sum += value;
min = Math.min(min, value);
max = Math.max(max, value);
}
/**
* Combines the state of another {@code IntSummaryStatistics} into
this one.
*
* @param other another {@code IntSummaryStatistics}
* @throws NullPointerException if {@code other} is null
*/
public void combine(IntSummaryStatistics other) {
count += other.count;
sum += other.sum;
min = Math.min(min, other.min);
max = Math.max(max, other.max);
}
}
More information about the lambda-dev
mailing list