★
操作符选择指南
| 场景 | 推荐操作符 |
|---|---|
| 转换每个元素 | map, mapIndexed |
| 过滤元素 | filter, take, drop |
| 查找元素 | find, first, last, single |
| 分组 | groupBy, partition |
| 排序 | sorted, sortedBy, sortedWith |
| 去重 | distinct, distinctBy |
| 找极值 | minBy, maxBy, minOf, maxOf |
| 转 Map | associateBy, associate, associateWith |
| 判断条件 | any, all, none, count |
| 累积计算 | fold, reduce, sum, average |
| 字符串输出 | joinToString |
| 合并集合 | zip, flatMap |
1
映射操作 (Mapping)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
map |
对每个元素进行转换 | list.map { it * 2 } // [2, 4, 6] |
mapNotNull |
映射并过滤掉 null | list.mapNotNull { it.takeIf { it > 1 } } |
mapIndexed |
带索引的映射 | list.mapIndexed { index, value -> "$index: $value" } |
flatMap |
映射并扁平化 | listOf(listOf(1,2), listOf(3,4)).flatMap { it } |
// map 示例
val numbers = listOf(1, 2, 3)
val doubled = numbers.map { it * 2 }
println(doubled) // [2, 4, 6]
// mapNotNull 示例
val strings = listOf("1", "a", "3", null, "5")
val ints = strings.mapNotNull { it?.toIntOrNull() }
println(ints) // [1, 3, 5]
// mapIndexed 示例
val indexed = numbers.mapIndexed { index, n -> "索引$index = $n" }
println(indexed) // [索引0 = 1, 索引1 = 2, 索引2 = 3]
// flatMap 示例
val nested = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6))
val flattened = nested.flatMap { it }
println(flattened) // [1, 2, 3, 4, 5, 6]
// flatMap 用于展开嵌套结构
val words = listOf("hello", "world")
val chars = words.flatMap { it.toList() }
println(chars) // [h, e, l, l, o, w, o, r, l, d]
2
过滤操作 (Filtering)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
filter |
按条件过滤元素 | list.filter { it > 2 } // [3, 4, 5] |
find |
查找第一个符合条件的元素 | list.find { it > 2 } // 3 |
findLast |
查找最后一个符合条件的元素 | list.findLast { it > 2 } // 5 |
// filter 示例
val numbers = listOf(1, 2, 3, 4, 5)
val evens = numbers.filter { it % 2 == 0 }
println(evens) // [2, 4]
val odds = numbers.filterNot { it % 2 == 0 }
println(odds) // [1, 3, 5]
// find 示例
val firstGreaterThan3 = numbers.find { it > 3 }
println(firstGreaterThan3) // 4
val firstGreaterThan10 = numbers.find { it > 10 }
println(firstGreaterThan10) // null
// findLast 示例
val lastGreaterThan3 = numbers.findLast { it > 3 }
println(lastGreaterThan3) // 5
3
分组操作 (Grouping)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
groupBy |
按条件分组 | list.groupBy { it % 2 } // {0=[2,4], 1=[1,3,5]} |
// groupBy 示例
data class Person(val name: String, val age: Int)
val people = listOf(
Person("Alice", 25),
Person("Bob", 30),
Person("Charlie", 25),
Person("David", 30)
)
// 按年龄分组
val byAge = people.groupBy { it.age }
println(byAge)
// {25=[Person(Alice, 25), Person(Charlie, 25)], 30=[Person(Bob, 30), Person(David, 30)]}
// 按首字母分组
val byFirstLetter = people.groupBy { it.name.first() }
println(byFirstLetter)
4
排序操作 (Sorting)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
sorted |
升序排序 | listOf(3,1,2).sorted() // [1,2,3] |
sortedDescending |
降序排序 | listOf(3,1,2).sortedDescending() // [3,2,1] |
sortedBy |
按指定属性升序 | people.sortedBy { it.age } |
sortedByDescending |
按指定属性降序 | people.sortedByDescending { it.age } |
sortedWith |
自定义比较器 | people.sortedWith(compareBy { it.age }) |
val numbers = listOf(3, 1, 4, 1, 5, 9, 2, 6)
// sorted 示例
val sorted = numbers.sorted()
println(sorted) // [1, 1, 2, 3, 4, 5, 6, 9]
val sortedDesc = numbers.sortedDescending()
println(sortedDesc) // [9, 6, 5, 4, 3, 2, 1, 1]
// sortedBy 示例
data class Product(val name: String, val price: Double)
val products = listOf(
Product("Apple", 2.5),
Product("Banana", 1.5),
Product("Cherry", 5.0)
)
val byPrice = products.sortedBy { it.price }
println(byPrice) // [Banana, Apple, Cherry]
// sortedWith 示例 - 多字段排序
val byPriceThenName = products.sortedWith(
compareBy<Product> { it.price }.thenBy { it.name }
)
5
去重操作 (Distinct)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
distinct |
去除重复元素 | listOf(1,2,2,3).distinct() // [1,2,3] |
distinctBy |
按指定属性去重 | people.distinctBy { it.age } |
// distinct 示例
val numbers = listOf(1, 2, 2, 3, 3, 3, 4)
val unique = numbers.distinct()
println(unique) // [1, 2, 3, 4]
// distinctBy 示例
data class User(val id: Int, val name: String, val email: String)
val users = listOf(
User(1, "Alice", "alice@example.com"),
User(2, "Bob", "bob@example.com"),
User(3, "Alice", "alice2@example.com")
)
// 按名字去重,保留第一个
val uniqueByName = users.distinctBy { it.name }
println(uniqueByName) // [User(1, Alice, ...), User(2, Bob, ...)]
6
极值操作 (Min/Max)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
minBy |
按条件找最小值 | people.minBy { it.age } |
maxBy |
按条件找最大值 | people.maxBy { it.age } |
minOf |
获取最小值 | people.minOf { it.age } |
maxOf |
获取最大值 | people.maxOf { it.age } |
data class Product(val name: String, val price: Double)
val products = listOf(
Product("Apple", 2.5),
Product("Banana", 1.5),
Product("Cherry", 5.0)
)
// minBy/maxBy 返回元素
val cheapest = products.minBy { it.price }
println(cheapest) // Product(Banana, 1.5)
val mostExpensive = products.maxBy { it.price }
println(mostExpensive) // Product(Cherry, 5.0)
// minOf/maxOf 返回属性值
val minPrice = products.minOf { it.price }
println(minPrice) // 1.5
val maxPrice = products.maxOf { it.price }
println(maxPrice) // 5.0
7
关联操作 (Association)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
associateBy |
转换为 Map(键由元素生成) | people.associateBy { it.id } |
associate |
转换为 Map(键值都由元素生成) | people.associate { it.name to it.age } |
associateWith |
转换为 Map(值为元素本身) | names.associateWith { it.length } |
// associateBy 示例 - 以 id 为键
data class Student(val id: Int, val name: String, val score: Int)
val students = listOf(
Student(1, "Alice", 85),
Student(2, "Bob", 90),
Student(3, "Charlie", 78)
)
val studentMap = students.associateBy { it.id }
println(studentMap)
// {1=Student(1, Alice, 85), 2=Student(2, Bob, 90), 3=Student(3, Charlie, 78)}
// 通过 id 快速查找
val student = studentMap[2]
println(student?.name) // Bob
// associate 示例 - 自定义键值对
val nameToScore = students.associate { it.name to it.score }
println(nameToScore) // {Alice=85, Bob=90, Charlie=78}
// associateWith 示例
val names = listOf("Alice", "Bob", "Charlie")
val nameLengths = names.associateWith { it.length }
println(nameLengths) // {Alice=5, Bob=3, Charlie=7}
8
元素获取 (Element Access)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
first |
获取第一个元素 | list.first() |
firstOrNull |
获取第一个元素或 null | list.firstOrNull() |
last |
获取最后一个元素 | list.last() |
lastOrNull |
获取最后一个元素或 null | list.lastOrNull() |
single |
获取唯一元素(集合必须只有一个) | list.single() |
singleOrNull |
获取唯一元素或 null | list.singleOrNull() |
val numbers = listOf(1, 2, 3, 4, 5)
// first/last 示例
println(numbers.first()) // 1
println(numbers.last()) // 5
// 带条件的 first
println(numbers.first { it > 3 }) // 4
// firstOrNull 安全获取
val empty = emptyList<Int>()
println(empty.firstOrNull()) // null
// single 示例 - 集合必须只有一个元素
val single = listOf(42)
println(single.single()) // 42
// singleOrNull 示例
println(listOf(42).singleOrNull()) // 42
println(listOf(1, 2).singleOrNull()) // null
println(emptyList<Int>().singleOrNull()) // null
9
判断操作 (Predicates)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
any |
是否有任意元素满足条件 | list.any { it > 0 } // true |
all |
是否所有元素都满足条件 | list.all { it > 0 } // false |
none |
是否没有元素满足条件 | list.none { it < 0 } // true |
count |
统计满足条件的元素数量 | list.count { it > 2 } // 3 |
val numbers = listOf(1, 2, 3, 4, 5)
// any 示例
val hasEven = numbers.any { it % 2 == 0 }
println(hasEven) // true
val hasNegative = numbers.any { it < 0 }
println(hasNegative) // false
// all 示例
val allPositive = numbers.all { it > 0 }
println(allPositive) // true
val allEven = numbers.all { it % 2 == 0 }
println(allEven) // false
// none 示例
val noNegative = numbers.none { it < 0 }
println(noNegative) // true
// count 示例
val evenCount = numbers.count { it % 2 == 0 }
println(evenCount) // 2
10
字符串连接 (Joining)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
joinToString |
将集合连接成字符串 | list.joinToString(", ") // "1, 2, 3" |
val numbers = listOf(1, 2, 3, 4, 5)
// 基本用法
val joined = numbers.joinToString()
println(joined) // 1, 2, 3, 4, 5
// 自定义分隔符
val withDash = numbers.joinToString(" - ")
println(withDash) // 1 - 2 - 3 - 4 - 5
// 完整参数
val formatted = numbers.joinToString(
separator = ", ", // 分隔符
prefix = "[", // 前缀
postfix = "]", // 后缀
limit = 3, // 最多显示3个
truncated = "..." // 超出部分显示...
)
println(formatted) // [1, 2, 3, ...]
// 自定义转换
data class Person(val name: String, val age: Int)
val people = listOf(Person("Alice", 25), Person("Bob", 30))
val names = people.joinToString(
separator = " | ",
transform = { it.name }
)
println(names) // Alice | Bob
11
累积操作 (Accumulation)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
fold |
带初始值的累积 | list.fold(0) { acc, n -> acc + n } // 15 |
reduce |
不带初始值的累积 | list.reduce { acc, n -> acc + n } // 15 |
val numbers = listOf(1, 2, 3, 4, 5)
// fold 示例 - 带初始值
val sum = numbers.fold(0) { accumulator, number ->
accumulator + number
}
println(sum) // 15
// fold 用于字符串拼接
val joined = numbers.fold("Numbers: ") { acc, n ->
"$acc$n "
}
println(joined) // Numbers: 1 2 3 4 5
// reduce 示例 - 不带初始值
val product = numbers.reduce { acc, n -> acc * n }
println(product) // 120 (1*2*3*4*5)
// runningFold - 返回中间结果
val runningSums = numbers.runningFold(0) { acc, n -> acc + n }
println(runningSums) // [0, 1, 3, 6, 10, 15]
// runningReduce
val runningProducts = numbers.runningReduce { acc, n -> acc * n }
println(runningProducts) // [1, 2, 6, 24, 120]
12
截取操作 (Take/Drop)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
take |
取前 n 个元素 | list.take(3) // [1,2,3] |
takeLast |
取后 n 个元素 | list.takeLast(3) // [3,4,5] |
takeWhile |
取满足条件的元素(遇到不满足停止) | list.takeWhile { it < 4 } // [1,2,3] |
drop |
跳过前 n 个元素 | list.drop(2) // [3,4,5] |
dropLast |
跳过后 n 个元素 | list.dropLast(2) // [1,2,3] |
dropWhile |
跳过满足条件的元素(遇到不满足停止) | list.dropWhile { it < 3 } // [3,4,5] |
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// take 示例
val first3 = numbers.take(3)
println(first3) // [1, 2, 3]
val last3 = numbers.takeLast(3)
println(last3) // [8, 9, 10]
// takeWhile 示例
val lessThan5 = numbers.takeWhile { it < 5 }
println(lessThan5) // [1, 2, 3, 4]
// drop 示例
val skipFirst3 = numbers.drop(3)
println(skipFirst3) // [4, 5, 6, 7, 8, 9, 10]
// 组合使用 - 分页
val pageSize = 3
val page2 = numbers.drop(pageSize).take(pageSize)
println(page2) // [4, 5, 6] (第2页)
13
合并操作 (Zipping)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
zip |
将两个集合合并为 Pair 列表 | list1.zip(list2) // [(1,a), (2,b)] |
zipWithNext |
将相邻元素配对 | list.zipWithNext() // [(1,2), (2,3)] |
// zip 示例
val numbers = listOf(1, 2, 3)
val letters = listOf("a", "b", "c")
val zipped = numbers.zip(letters)
println(zipped) // [(1, a), (2, b), (3, c)]
// 自定义合并方式
val combined = numbers.zip(letters) { n, l ->
"$l$n"
}
println(combined) // [a1, b2, c3]
// zipWithNext 示例
val adjacent = numbers.zipWithNext()
println(adjacent) // [(1, 2), (2, 3)]
// 用于计算差值
val diffs = numbers.zipWithNext { a, b -> b - a }
println(diffs) // [1, 1]
// unzip - 反向操作
val pairs = listOf(1 to "a", 2 to "b", 3 to "c")
val (nums, strs) = pairs.unzip()
println(nums) // [1, 2, 3]
println(strs) // [a, b, c]
14
分区操作 (Partitioning)
| 操作符 | 作用 | 示例代码 |
|---|---|---|
partition |
按条件分成两个集合 | list.partition { it > 3 } // ([4,5], [1,2,3]) |
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// partition 示例 - 分成奇偶两组
val (evens, odds) = numbers.partition { it % 2 == 0 }
println(evens) // [2, 4, 6, 8, 10]
println(odds) // [1, 3, 5, 7, 9]
// 实际应用 - 分离通过和未通过的学生
data class Student(val name: String, val score: Int)
val students = listOf(
Student("Alice", 85),
Student("Bob", 45),
Student("Charlie", 92),
Student("David", 58),
Student("Eve", 76)
)
val (passed, failed) = students.partition { it.score >= 60 }
println("通过的学生:")
passed.forEach { println(" ${it.name}: ${it.score}") }
println("未通过的学生:")
failed.forEach { println(" ${it.name}: ${it.score}") }
★
综合示例
data class Employee(
val id: Int,
val name: String,
val department: String,
val salary: Double,
val yearsOfService: Int
)
fun main() {
val employees = listOf(
Employee(1, "Alice", "Engineering", 80000.0, 5),
Employee(2, "Bob", "Sales", 60000.0, 3),
Employee(3, "Charlie", "Engineering", 90000.0, 7),
Employee(4, "David", "HR", 50000.0, 2),
Employee(5, "Eve", "Sales", 75000.0, 4),
Employee(6, "Frank", "Engineering", 85000.0, 6)
)
// 1. 找出工程部员工并按工资排序
val engineers = employees
.filter { it.department == "Engineering" }
.sortedByDescending { it.salary }
println("工程部员工(按工资排序): ${engineers.map { it.name }}")
// 2. 按部门分组并计算平均工资
val avgSalaryByDept = employees
.groupBy { it.department }
.mapValues { (_, empList) ->
empList.map { it.salary }.average()
}
println("各部门平均工资: $avgSalaryByDept")
// 3. 找出工资最高的员工
val highestPaid = employees.maxBy { it.salary }
println("工资最高: ${highestPaid.name} - $${highestPaid.salary}")
// 4. 统计服务年限超过5年的员工
val seniorEmployees = employees.filter { it.yearsOfService > 5 }
println("资深员工数量: ${seniorEmployees.count()}")
// 5. 生成员工名单字符串
val nameList = employees
.sortedBy { it.name }
.joinToString(
separator = ", ",
prefix = "员工名单: ",
transform = { it.name }
)
println(nameList)
// 6. 分区:高薪 vs 普通员工
val (highPaid, regular) = employees.partition { it.salary >= 70000 }
println("高薪员工: ${highPaid.map { it.name }}")
println("普通员工: ${regular.map { it.name }}")
// 7. 计算总工资支出
val totalSalary = employees.sumOf { it.salary }
println("总工资支出: $$totalSalary")
// 8. 按服务年限分组
val byServiceYears = employees.groupBy {
when {
it.yearsOfService < 3 -> "Junior"
it.yearsOfService < 6 -> "Mid"
else -> "Senior"
}
}
println("按年限分组: ${byServiceYears.mapValues { (_, v) -> v.map { it.name } }}")
}