kotlin中好用的集合扩展函数

first和firstOrNull

kotlin 复制代码
val tm = App.app.getSystemService(TELEPHONY_SERVICE) as TelephonyManager
val cellInfos = tm.allCellInfo // getAllCellInfo() 来自 Android 4.2

val isLte: ((CellInfo) -> Boolean) = { cellInfo: CellInfo ->
    cellInfo is CellInfoLte // CellInfoLte 来自 Android 4.2
}

val isNr: ((CellInfo) -> Boolean) = { cellInfo: CellInfo ->
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        cellInfo is CellInfoNr // CellInfoNr 在Android 10
    } else {
        false
    }
}

val cellInfoList = cellInfos?.filter { it.isRegistered && (isLte(it) || isNr(it)) }

if (cellInfoList.isNullOrEmpty()) {
    return null
}

// 优先获取5G
val cellInfo: CellInfo = cellInfoList.firstOrNull(isNr) ?: cellInfoList.first(isLte)

如上示例代码,功能为获取Android设备的蜂窝信息,下面代码获取了LTE或NR(即4G或5G)的信息:

kotlin 复制代码
val cellInfoList = cellInfos?.filter { it.isRegistered && (isLte(it) || isNr(it)) }
if (cellInfoList.isNullOrEmpty()) {
    return null
}

如上代码保证了cellInfoList 集合中数据不为空,且数据要么是LTE要么是NR类型的,下面代码优雅的实现了NR(即5G)数据优先使用:

kotlin 复制代码
val cellInfo: CellInfo = cellInfoList.firstOrNull(isNr) ?: cellInfoList.first(isLte)

firstOrNull允许结果为nullfirst则不允许结果为null,因为我们确定集合里面最少会有其中一种类型的数据,所以最后可以使用first来获取数据,这是安全的,这样我们终最得到的CellInfo 对象就是绝对不可能为null的对象,所以不用声明为CellInfo?

集合中还有一个find函数,它底层是调用的firstOrNull,所以我们尽量使用firstOrNull,不用find,因为firstOrNull功能更显而易见。

集合中还有很多好用的扩展函数,声明在_Collections.kt中,比如:

🧺 一、过滤类(filter)

filter

保留满足条件的元素

复制代码
val nums = listOf(1, 2, 3, 4, 5)
val evens = nums.filter { it % 2 == 0 }
// [2, 4]

filterNot

过滤掉满足条件的

复制代码
val evens = nums.filterNot { it % 2 == 0 }
// [1, 3, 5]

👀 filterNotNull

去掉 null

复制代码
val list = listOf("A", null, "B")
val result = list.filterNotNull()
// ["A", "B"]

🔄 二、映射类(map)

🔁 map

把元素变成另一种形式

复制代码
val nums = listOf(1, 2, 3)
val squares = nums.map { it * it }
// [1, 4, 9]

🧹 mapNotNull

转换 + 去 null

复制代码
val list = listOf("1", "a", "3")
val numbers = list.mapNotNull { it.toIntOrNull() }
// [1, 3]

🧵 flatMap

一对多展开

复制代码
val words = listOf("Hi", "Bye")
val chars = words.flatMap { it.toList() }
// [H, i, B, y, e]

📦 三、查找类

🔍 find / firstOrNull

复制代码
val nums = listOf(3, 7, 10)
val firstBig = nums.find { it > 5 }   // 7
val maybe = nums.firstOrNull { it > 20 } // null

🏁 any / all / none

复制代码
nums.any { it > 8 }   // true
nums.all { it > 0 }   // true
nums.none { it < 0 }  // true

📊 四、分组 & 统计

🧮 groupBy

按条件分组

复制代码
val names = listOf("Tom", "Tim", "Lucy")
val grouped = names.groupBy { it.first() }
// {T=[Tom, Tim], L=[Lucy]}

🔢 count

复制代码
nums.count { it % 2 == 0 } // 偶数个数

📐 五、排序

⬆️ sorted

复制代码
val nums = listOf(5, 1, 3)
nums.sorted() // [1, 3, 5]

🔽 sortedBy

复制代码
data class User(val name: String, val age: Int)

val users = listOf(
    User("A", 30),
    User("B", 20)
)

users.sortedBy { it.age }

🎯 六、取元素

🎯 take / takeLast

复制代码
nums.take(2)      // 前两个
nums.takeLast(2)  // 后两个

✂️ drop / dropLast

复制代码
nums.drop(2)      // 去掉前两个
nums.dropLast(1)  // 去掉最后一个

🔗 七、集合转换

🧱 toSet() 去重

复制代码
listOf(1,1,2,2,3).toSet() // [1,2,3]

🗂 associateBy

复制代码
val usersByName = users.associateBy { it.name }
// Map<String, User>

➕ 八、聚合运算

sumOf

复制代码
nums.sumOf { it }  // 求和

📦 reduce

复制代码
nums.reduce { acc, i -> acc + i } // 累加

🛟 fold(带初始值)

复制代码
nums.fold(10) { acc, i -> acc + i } // 从10开始加

🧩 九、拼接 & 字符串

🧵 joinToString

复制代码
nums.joinToString(", ") // "1, 2, 3"

🧠 十、去重(进阶)

🧼 distinct

复制代码
listOf(1,2,2,3).distinct() // [1,2,3]

🧬 distinctBy

复制代码
users.distinctBy { it.age }

🚀 实战味最浓的一行代码组合

复制代码
val result = users
    .filter { it.age > 18 }
    .sortedBy { it.age }
    .map { it.name }
    .joinToString()

👉 过滤 → 排序 → 映射 → 拼接

这就是 Kotlin 集合 API 的精髓链式写法。

🏆 Android 开发中最常用的 Kotlin 集合操作 TOP 15


1️⃣ 接口数据去空 + 防崩

场景: 服务器返回的数据有 null

复制代码
val validUsers = response.users.filterNotNull()

2️⃣ 过滤无效数据(状态判断)

场景: 只显示"在线设备"

复制代码
val onlineDevices = devices.filter { it.isOnline }

3️⃣ RecyclerView 列表去重(按ID)

场景: 接口重复数据

复制代码
val distinctList = list.distinctBy { it.id }

4️⃣ 按时间排序(聊天、日志)

复制代码
val sorted = messages.sortedByDescending { it.timestamp }

5️⃣ 查找某个元素(是否存在)

复制代码
val hasError = logs.any { it.level == "ERROR" }

6️⃣ 找到第一个符合条件的数据

复制代码
val firstUnread = messages.firstOrNull { !it.read }

7️⃣ 列表 → Map(快速查找)

场景: 根据 userId 快速找用户

复制代码
val userMap = users.associateBy { it.id }
val user = userMap[1001]

8️⃣ Map → List(用于显示)

复制代码
val userList = userMap.values.toList()

9️⃣ 分组显示(联系人分组)

复制代码
val grouped = contacts.groupBy { it.name.first().uppercaseChar() }

🔟 统计数量(角标/徽章)

复制代码
val unreadCount = messages.count { !it.read }

1️⃣1️⃣ 求和(流量、电量、金额)

复制代码
val total = orders.sumOf { it.price }

1️⃣2️⃣ 扁平化列表(多层数据展开)

场景: 多个文件夹里的文件合并

复制代码
val allFiles = folders.flatMap { it.files }

1️⃣3️⃣ 安全转换类型(字符串转数字)

复制代码
val numbers = strings.mapNotNull { it.toIntOrNull() }

1️⃣4️⃣ 取前几个(首页展示)

复制代码
val top3 = newsList.take(3)

1️⃣5️⃣ 拼接字符串(日志 / 展示)

复制代码
val names = users.joinToString(", ") { it.name }

🌟 进阶组合写法(面试 & 实战高频)

👉 过滤 + 排序 + 转换 + 展示

复制代码
val displayText = orders
    .filter { it.status == "PAID" }
    .sortedByDescending { it.time }
    .map { "${it.name} ¥${it.price}" }
    .joinToString("\n")

🧠 一张脑图式总结

目的 常用函数
过滤数据 filter filterNotNull
查找判断 any firstOrNull find
排序 sortedBy sortedByDescending
去重 distinctBy
统计 count sumOf
分组 groupBy
映射转换 map mapNotNull
扁平化 flatMap
截取 take drop
结构转换 associateBy toList
拼接显示 joinToString

这些基本覆盖了 90% Android 业务代码中的集合操作

相关推荐
jinanwuhuaguo16 小时前
OpenClaw联邦之心——从孤岛记忆到硅基集体潜意识的拓扑学革命(第二十三篇)
android·人工智能·kotlin·拓扑学·openclaw
pengyu20 小时前
【Kotlin 协程修仙录 · 筑基境 · 后阶】 | 调度器的艺术:Dispatchers 四大护法与 withContext 性能密码
android·kotlin
千码君201621 小时前
flutter: 分享一下基于trae cn 构建的过程
java·vscode·flutter·kotlin·trae
小书房2 天前
Kotlin的内联函数
java·开发语言·kotlin·inline·内联函数
zhangphil2 天前
Android Page3与Flow分页查媒体数据库展示宫格图片列表,Kotlin
android·kotlin
胡致和3 天前
配置变更后,弹窗为什么飞到了最左边?
kotlin
zhangphil3 天前
Android Page 3 Flow读sql数据库媒体文件,Kotlin
android·kotlin
小书房3 天前
Kotlin使用体验及理解1
android·开发语言·kotlin
Kapaseker3 天前
我想让同事知道我很懂 Compose 怎么办?
android·kotlin
jinanwuhuaguo3 天前
OpenClaw工程解剖——RAG、向量织构与“记忆宫殿”的索引拓扑学(第十三篇)
android·开发语言·人工智能·kotlin·拓扑学·openclaw