在summarizingInt
收集工作得很好,如果你有一个整数流.
IntSummaryStatistics stats = Stream.of(2,4,3,2) .collect(Collectors.summarizingInt(Integer::intValue)); int min = stats.getMin(); int max = stats.getMax();
如果你有双打,你可以使用summarizingDouble
收藏家.
DoubleSummaryStatistics stats2 = Stream.of(2.4, 4.3, 3.3, 2.5) .collect(Collectors.summarizingDouble((Double::doubleValue)));
如果这是一个经常需要的功能,我们最好做一个Collector
工作.我们需要一个Stats
类来保持count, min, max
,以及工厂方法来创建统计信息收集器.
Statsstats = stringStream.collect(Stats.collector()) fooStream.collect(Stats.collector(fooComparator))
(也许更好的方便方法Stats.collect(stream)
)
我做了一个例子Stats
课 -
https://gist.github.com/zhong-j-yu/ac5028573c986f7820b25ea2e74ed672
public class Stats{ int count; final Comparator super T> comparator; T min; T max; public Stats(Comparator super T> comparator) { this.comparator = comparator; } public int count(){ return count; } public T min(){ return min; } public T max(){ return max; } public void accept(T val) { if(count==0) min = max = val; else if(comparator.compare(val, min)<0) min = val; else if(comparator.compare(val, max)>0) max = val; count++; } public Stats combine(Stats that) { if(this.count==0) return that; if(that.count==0) return this; this.count += that.count; if(comparator.compare(that.min, this.min)<0) this.min = that.min; if(comparator.compare(that.max, this.max)>0) this.max = that.max; return this; } public static Collector , Stats > collector(Comparator super T> comparator) { return Collector.of( ()->new Stats<>(comparator), Stats::accept, Stats::combine, Collector.Characteristics.UNORDERED, Collector.Characteristics.IDENTITY_FINISH ); } public static > Collector , Stats > collector() { return collector(Comparator.naturalOrder()); } }
将流的每个元素映射到一对,其中两个元素表示最小值和最大值; 然后通过获取分钟的最小值和最大值来减少对.
例如,使用某些Pair
类和一些Comparator
:
Comparatorcomparator = ...; Optional > minMax = list.stream() .map(i -> Pair.of(i /* "min" */, i /* "max" */)) .reduce((a, b) -> Pair.of( // The min of the min elements. comparator.compare(a.first, b.first) < 0 ? a.first : b.first, // The max of the max elements. comparator.compare(a.second, b.second) > 0 ? a.second : b.second));