研究表明,开发者对Kotlin集合的了解不到 20%

HR:你有多少年 Kotlin 使用经验?

候选人:5 年!

双方都挺满意。但你真的觉得,做了五年 Android 开发,就把 Kotlin 用透吗?或许你只用到了它的 20%。

我深入研究 Kotlin 时才发现,我就是个"伪 Kotlin 开发者"------它有太多强大的方法、扩展函数,还有很多我从没接触过的特性。

做算法题时,一看到数组,脑子里第一反应就是写个 for 循环。

但如果你用 Kotlin 解决问题,其实有很多更优雅的替代方案。

这篇文章,我会把 Kotlin 集合的惯用写法过一遍,它们会彻底改变你的代码风格。

Kotlin 标准库提供了极其丰富的集合操作,让你能写出简洁、可读、安全且高效 的代码。使用地道的 Kotlin 写法,可以帮你避免样板循环、手动映射、计数器变量等冗余代码。

转换:map 和 flatMap

作用:对集合里的每一个元素进行转换。

kotlin 复制代码
val names = listOf("Alice", "Bob")
val upper = names.map { it.uppercase() } // [ALICE, BOB]
val indexed = names.mapIndexed { i, n -> "$i:$n" } // [0:Alice, 1:Bob]

val nested = listOf(listOf(1,2), listOf(3,4))
val flatDoubled = nested.flatMap { it.map { it * 2 } } // [2,4,6,8]
函数 时间复杂度 说明
map / mapIndexed O(n) 适合转换数组/列表,避免在嵌套循环里使用
flatMap / flatMapIndexed O(n) 展平嵌套列表后使用 map

应用场景:数据库实体转换、展平嵌套订单、给商品价格打折等。

过滤:filter 和 take

kotlin 复制代码
val nums = listOf(1,2,3,4,5)
val evens = nums.filter { it % 2 == 0 }      // [2,4]
val firstThree = nums.take(3)                // [1,2,3]
val restAfterTwo = nums.drop(2)              // [3,4,5]
val underFours = nums.takeWhile { it < 4 }   // [1,2,3]
函数 时间复杂度 说明
filter O(n) 线性遍历
take(k) / drop(k) O(k) 高效切片
takeWhile / dropWhile O(n) 条件不满足就停止

应用场景:筛选活跃用户、列表分页、过滤事件、跳过已处理订单等。

查找

kotlin 复制代码
val words = listOf("apple", "banana", "cherry")
val firstB = words.firstOrNull { it.startsWith('b') } // banana

println(words.any { it.length > 5 })  // true
println(words.all { it.length > 0 })  // true
函数 时间复杂度 说明
firstOrNull / find O(n) 找到就停
lastOrNull O(n) 从头遍历到尾
any / all / none O(n) 最坏 能提前终止

应用场景:按 ID 查找用户、检查是否有失败交易、校验输入合法性等。

去重:distinct

kotlin 复制代码
val numbers = listOf(1,2,2,3)
val unique = numbers.distinct() // [1,2,3]
函数 时间复杂度 说明
distinct() O(n) 内部用 HashSet
distinctBy O(n) 按指定 key 去重

应用场景:标签去重、邮箱去重、商品 ID 去重等。

分组与分区:group 与 partition

kotlin 复制代码
val names = listOf("Alice", "Bob", "Anna")
val grouped = names.groupBy { it.first() }
// {A=[Alice, Anna], B=[Bob]}

val (even, odd) = listOf(1,2,3,4).partition { it % 2 == 0 }
// even=[2,4], odd=[1,3]

val letters = listOf('a','b','a')
val counts = letters.groupingBy { it }.eachCount() // {a=2, b=1}
函数 时间复杂度 说明
groupBy O(n) 转成 Map 列表
partition O(n) 分成两个列表
groupingBy.eachCount() O(n) 高效统计频次

应用场景:商品分类、任务划分、统计频率、按角色分组用户等。

排序:sort

kotlin 复制代码
data class User(val name: String, val salary: Int)
val users = mutableListOf(User("John",5000), User("Alice",7000))

// 返回新的排序后的列表
val sortedUsers = users.sortedWith(
    compareByDescending<User> { it.salary }.thenBy { it.name }
)

// 原地排序
users.sortWith(
    compareByDescending<User> { it.salary }.thenBy { it.name }
)
函数 时间复杂度 说明
sorted / sortedBy / sortedWith O(n log n) 返回新列表,稳定排序
sortWith O(n log n) 原地修改

应用场景:排行榜、薪资排序、优先级队列等。

聚合与归约:fold、reduce、sumOf

kotlin 复制代码
val nums = listOf(1,2,3)
val sum = nums.fold(0) { acc, n -> acc + n }    // 6
val product = nums.reduce { acc, n -> acc * n } // 6
val totalSalary = users.sumOf { it.salary }     // 12000
函数 时间复杂度 说明
fold / reduce O(n) 线性遍历累加
sumOf O(n) 直接求和

应用场景:计算总收入、库存估值、指标乘积等。

键值映射:associateBy 和 zip

kotlin 复制代码
val mapByName = users.associateBy { it.name }
// {"John"=User("John",5000), "Alice"=User("Alice",7000)}

val scores = listOf(90, 80)
val zipped = listOf("Alice", "Bob").zip(scores) { name, score ->
    "$name scored $score"
}
// ["Alice scored 90", "Bob scored 80"]
函数 时间复杂度 说明
associateBy / associateWith O(n) 生成 HashMap
zip O(n) 两两组合

应用场景:构建查找表、生成报表、名称与数值配对等。

展平:flat

kotlin 复制代码
val nested = listOf(listOf(1,2), listOf(3,4))
val flat = nested.flatten() // [1,2,3,4]

val flatDoubled = nested.flatMap { it.map { it*2 } } // [2,4,6,8]
函数 时间复杂度 说明
flatten() O(n) n 为总元素数
flatMap() O(n) 展平 + 转换

应用场景:展平订单结构、批量转换列表项等。

惰性求值:asSequence

kotlin 复制代码
val numbers = (1..1_000_000).asSequence()
val result = numbers.map { it * 2 }
                .filter { it % 3 == 0 }
                .take(5)
                .toList()
函数 时间复杂度 说明
asSequence O(1) 创建 惰性求值,只有终端操作才真正执行

应用场景:高效处理超大数据集、日志流、大型计算等。

窗口与分块:window 和 chunked

kotlin 复制代码
val numbers = (1..5).toList()
println(numbers.windowed(3)) // [[1,2,3],[2,3,4],[3,4,5]]
println(numbers.chunked(2))  // [[1,2],[3,4],[5]]
函数 时间复杂度 说明
windowed(k) O(n*k) 窗口复制,k 大时注意性能
chunked(k) O(n) 线性分块

应用场景:数据分析、滑动平均、批量处理等。

带索引遍历:index

kotlin 复制代码
val names = listOf("Alice", "Bob")
for ((index, name) in names.withIndex()) {
    println("$index -> $name")
}
函数 时间复杂度 说明
withIndex O(n) 无额外开销
mapIndexed O(n) 带索引转换

应用场景:设置位置、展示排名、显示行号等。

副作用:onEach

kotlin 复制代码
val doubled = (1..5).map { it*2 }
                 .onEach { println(it) }
                 .toList()
函数 时间复杂度 说明
onEach O(n) 对每个元素执行操作

应用场景:链式调用中打印日志、调试、触发事件等。

条件返回:takeIf

kotlin 复制代码
val number = 10
println(number.takeIf { it % 2 == 0 })     // 10
println(number.takeUnless { it % 2 == 0 }) // null
函数 时间复杂度 说明
takeIf / takeUnless O(1) 仅做一次条件判断

应用场景:内联校验、可选过滤、适配链式调用。

安全访问

kotlin 复制代码
val arr = listOf(10, 20)
val second = arr.getOrNull(1) // 越界返回 null
函数 时间复杂度 说明
getOrNull O(1) 避免越界异常

函数式序列:generateSequence

kotlin 复制代码
val fib = generateSequence(Pair(0,1)) {
    Pair(it.second, it.first + it.second)
}
    .map { it.first }
    .take(10)
    .toList()

println(fib) // [0,1,1,2,3,5,8,13,21,34]
函数 时间复杂度 说明
generateSequence 每个元素 O(1) 惰性,可生成无限序列

应用场景:斐波那契数列、惰性事件流、无限生成器等。

相关推荐
catoop10 分钟前
Android 最佳实践、分层架构与全流程解析(2025)
android
ZHANG13HAO39 分钟前
Android 13 特权应用(Android Studio 开发)调用 AOSP 隐藏 API 完整教程
android·ide·android studio
田梓燊1 小时前
leetcode 142
android·java·leetcode
angerdream1 小时前
Android手把手编写儿童手机远程监控App之JAVA基础
android
菠萝地亚狂想曲2 小时前
Zephyr_01, environment
android·java·javascript
sTone873752 小时前
跨端框架通信机制全解析:从 URL Schema 到 JSI 到 Platform Channel
android·前端
sTone873752 小时前
Java 注解完全指南:从 "这是什么" 到 "自己写一个"
android·前端
catoop2 小时前
Kotlin 协程在 Android 开发中的应用:定义、优势与对比
android·kotlin
撒旦物种2 小时前
Android WebView 获取内容高度
android·webview
空中海3 小时前
第七章:安卓性能优化
android·性能优化