Kotlin 收集示例#7b-使用SummarizingInt收集
示例
//Java: IntSummaryStatistics ageSummary = persons.stream() .collect(Collectors.summarizingInt(p -> p.age)); System.out.println(ageSummary); //IntSummaryStatistics{count=4,sum=76,min=12,average=19.000000,max=23}
//科特林: //保持统计数据的东西... data class SummaryStatisticsInt(var count: Int = 0, var sum: Int = 0, var min: Int = Int.MAX_VALUE, var max: Int = Int.MIN_VALUE, var avg: Double = 0.0) { fun accumulate(newInt: Int): SummaryStatisticsInt { count++ sum += newInt min = min.coerceAtMost(newInt) max = max.coerceAtLeast(newInt) avg = sum.toDouble() / count return this } } //现在手动进行折叠,因为Stream.collect实际上只是折叠 val stats = persons.fold(SummaryStatisticsInt()) { stats, person -> stats.accumulate(person.age) } println(stats) //输出:SummaryStatisticsInt(count=4,sum=76,min=12,max=23,avg=19.0)
但是最好创建一个扩展功能,2实际上是要匹配Kotlinstdlib中的样式:
//科特林: inline fun Collection<Int>.summarizingInt(): SummaryStatisticsInt = this.fold(SummaryStatisticsInt()) { stats, num -> stats.accumulate(num) } inline fun <T: Any> Collection<T>.summarizingInt(transform: (T)->Int): SummaryStatisticsInt = this.fold(SummaryStatisticsInt()) { stats, item -> stats.accumulate(transform(item)) }
现在,您有两种使用新summarizingInt功能的方法:
val stats2 =persons.map{it.age}.summarizingInt() //要么 val stats3 =persons.summarizingInt{it.age}
所有这些产生相同的结果。我们还可以创建此扩展,以在Sequence适当的原始类型上工作并适用于它们。