Kotlin聚合方法
在前面的主题中,我们学习了如何对集合进行排序或基于谓词过滤集合元素。
现在是时候学习如何根据集合的内容获取值了,例如:最大值、平均值、具有最大某个属性值的对象等等。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()) // 1println(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 }) // carolineprintln(words.minByOrNull { it.length }) // anne// 最大/最小长度值println(words.maxOfOrNull { it.length }) // 8println(words.minOfOrNull { it.length }) // 4// 所有单词长度之和println(words.sumOf { it.length }) // 32// 使用谓词进行计数和查找println(words.count { it.length > 5 }) // 4println(words.maxByOrNull { it.length > 5 }) // michaelprintln(words.minByOrNull { it.length > 5 }) // anne// 空集合val emptyWordsList = emptyList<String>()println(emptyWordsList.count()) // 0println(emptyWordsList.maxByOrNull { it.length }) // nullprintln(emptyWordsList.minByOrNull { it.length }) // nullprintln(emptyWordsList.maxOfOrNull { it.length }) // nullprintln(emptyWordsList.minOfOrNull { it.length }) // nullprintln(emptyWordsList.maxOf { it.length }) // 抛出 NoSuchElementExceptionprintln(emptyWordsList.minOf { it.length }) // 抛出 NoSuchElementExceptionprintln(emptyWordsList.maxBy { it.length }) // 抛出 NoSuchElementExceptionprintln(emptyWordsList.minBy { it.length }) // 抛出 NoSuchElementException
}
解释代码:
-
maxByOrNull
和minByOrNull
会返回属性值最大的元素,而不是值本身。 -
maxOfOrNull
和minOfOrNull
返回的是选择器结果的最大/最小值。 -
使用谓词如
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 })) // carolineprintln(words.minWithOrNull(compareBy { it.length })) // anne// 使用比较器获取最大最小的长度值println(words.maxOfWithOrNull(naturalOrder()) { it.length }) // 8println(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]
是获取字符串的中间字符,根据它来排序也可以。
总结
在本节中,我们学习了各种用于获取集合中值的聚合方法,包括:
-
获取最大/最小值。
-
获取平均值、总和。
-
查找具有最大某个属性值的元素。
-
使用选择器或比较器自定义排序和聚合方式。