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适当的原始类型上工作并适用于它们。