研究表明,开发者对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) 惰性,可生成无限序列

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

相关推荐
bqliang2 小时前
Compose 媒体查询 (Media Query API) 🖱️👇🕹️
android·android jetpack
程序员陆业聪11 小时前
Android 平台 AI Agent 技术架构深度解析
android·人工智能
BD_Marathon16 小时前
工厂方法模式
android·java·工厂方法模式
王码码203516 小时前
Flutter for OpenHarmony:socket_io_client 实时通信的事实标准(Node.js 后端的最佳拍档) 深度解析与鸿蒙适配指南
android·flutter·ui·华为·node.js·harmonyos
勇气要爆发17 小时前
吴恩达《LangChain LLM 应用开发精读笔记》2-Models, Prompts and Parsers 模型、提示和解析器
android·笔记·langchain
Railshiqian17 小时前
给android源码下的模拟器添加两个后排屏的修改
android·开发语言·javascript
糖猫猫cc17 小时前
Kite:两种方式实现动态表名
java·kotlin·orm·kite
恋猫de小郭18 小时前
Flutter 的真正价值是什么?深度解析再结合鸿蒙,告诉你 Flutter 的真正优势
android·前端·flutter
Ehtan_Zheng19 小时前
我们如何在不减少功能的前提下,将安卓应用体积缩减 60%
android