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