Kotlin聚合方法

发布于:2025-07-18 ⋅ 阅读:(17) ⋅ 点赞:(0)

在前面的主题中,我们学习了如何对集合进行排序或基于谓词过滤集合元素。

现在是时候学习如何根据集合的内容获取值了,例如:最大值、平均值、具有最大某个属性值的对象等等。Kotlin 提供了非常方便的方法来完成这些任务,这些方法被称为“聚合方法(aggregation methods)”。


基本聚合函数

当我们处理集合时,可以使用一系列方法根据集合的内容获取某些值或额外信息,这些方法包括:

  • minOrNull():返回集合中最小的元素,若集合为空则返回 null

  • maxOrNull():返回集合中最大的元素,若集合为空则返回 null

  • average():返回数值集合的平均值。

  • sum():返回数值集合所有元素的总和。

  • count():返回集合中的元素数量。

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

    // 最小值和最大值
    println(numbers.minOrNull()) // 1
    println(numbers.maxOrNull()) // 10
    
    // 平均值
    println(numbers.average()) // 5.5
   
    // 总和
    println(numbers.sum()) // 55
    
    // 元素数量
    println(numbers.count()) // 10
}
解释代码:

这个程序使用了基础的聚合方法来处理一个整数列表。你可以轻松获得最大值、最小值、平均数、总和和元素数量。


带选择器函数的聚合

有时候我们需要指定使用哪个属性进行聚合操作。Kotlin 提供了**带选择器函数(selector function)**的专用方法:

  • minByOrNull { }:返回具有最小属性值的元素(集合为空时返回 null)。

  • maxByOrNull { }:返回具有最大属性值的元素(集合为空时返回 null)。

  • minOfOrNull { }:返回所有选择器函数结果中的最小值(集合为空时返回 null)。

  • maxOfOrNull { }:返回所有选择器函数结果中的最大值(集合为空时返回 null)。

  • sumOf { }:返回将选择器函数应用于每个元素后的结果之和。

fun main() {
    val words = listOf("anne", "michael", "caroline", "dimitry", "emilio")

    // 元素个数
    println(words.count()) // 5

    // 根据长度选择最大/最小的字符串
    println(words.maxByOrNull { it.length }) // caroline
    println(words.minByOrNull { it.length }) // anne
    
    // 最大/最小长度值
    println(words.maxOfOrNull { it.length }) // 8
    println(words.minOfOrNull { it.length }) // 4
    
    // 所有单词长度之和
    println(words.sumOf { it.length }) // 32

    // 使用谓词进行计数和查找
    println(words.count { it.length > 5 }) // 4
    println(words.maxByOrNull { it.length > 5 }) // michael
    println(words.minByOrNull { it.length > 5 }) // anne

    // 空集合
    val emptyWordsList = emptyList<String>()
    println(emptyWordsList.count()) // 0
    println(emptyWordsList.maxByOrNull { it.length }) // null
    println(emptyWordsList.minByOrNull { it.length }) // null
    println(emptyWordsList.maxOfOrNull { it.length }) // null
    println(emptyWordsList.minOfOrNull { it.length }) // null
    println(emptyWordsList.maxOf { it.length })  // 抛出 NoSuchElementException
    println(emptyWordsList.minOf { it.length })  // 抛出 NoSuchElementException
    println(emptyWordsList.maxBy { it.length })  // 抛出 NoSuchElementException
    println(emptyWordsList.minBy { it.length })  // 抛出 NoSuchElementException
}
解释代码:
  • maxByOrNullminByOrNull 会返回属性值最大的元素,而不是值本身。

  • maxOfOrNullminOfOrNull 返回的是选择器结果的最大/最小值。

  • 使用谓词如 it.length > 5 会将 true/false 当作比较依据,true > false,所以 maxByOrNull 返回第一个满足条件的元素。


使用比较器聚合(Comparator)

你也可以通过传递自定义比较器来执行类似操作:

  • minWithOrNull(comparator)

  • maxWithOrNull(comparator)

  • minOfWithOrNull(comparator) { }

  • maxOfWithOrNull(comparator) { }

这些方法在集合为空时返回 null,而它们的非 OrNull 版本(如 maxWith())在集合为空时会抛出异常。

fun main() {
    val words = listOf("anne", "michael", "caroline", "dimitry", "emilio")

    // 自定义比较器:长度排序
    println(words.maxWithOrNull(compareBy { it.length })) // caroline
    println(words.minWithOrNull(compareBy { it.length })) // anne

    // 使用比较器获取最大最小的长度值
    println(words.maxOfWithOrNull(naturalOrder()) { it.length }) // 8
    println(words.minOfWithOrNull(naturalOrder()) { it.length }) // 4

    // 使用谓词计数
    println(words.count { it.first() == 'a' }) // 1
}

反转排序结果

你可以将比较器与 reversed() 组合,获取相反顺序的结果:

fun main() {
    val words = listOf("peter", "anne", "michael", "caroline")

    // 按长度排序后反转
    println(words.sortedWith(compareBy { it.length }).reversed()) // [caroline, michael, peter, anne]
    
    // 按中间字母排序后反转
    println(words.sortedWith(compareBy { it[it.length / 2] }).reversed()) // [peter, anne, caroline, michael]
}
解释代码:
  • compareBy { it.length } 是一个比较器,会按单词长度排序。

  • reversed() 会将排序结果倒序。

  • it[it.length / 2] 是获取字符串的中间字符,根据它来排序也可以。


总结

在本节中,我们学习了各种用于获取集合中值的聚合方法,包括:

  • 获取最大/最小值。

  • 获取平均值、总和。

  • 查找具有最大某个属性值的元素。

  • 使用选择器或比较器自定义排序和聚合方式。


网站公告

今日签到

点亮在社区的每一天
去签到