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 业务代码中的集合操作

相关推荐
儿歌八万首1 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节
消失的旧时光-19433 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
有位神秘人3 小时前
kotlin与Java中的单例模式总结
java·单例模式·kotlin
Jinkxs3 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&3 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
golang学习记4 小时前
IntelliJ IDEA 2025.3 重磅发布:K2 模式全面接管 Kotlin —— 告别 K1,性能飙升 40%!
java·kotlin·intellij-idea
gjxDaniel2 天前
Kotlin编程语言入门与常见问题
android·开发语言·kotlin
野生技术架构师2 天前
Java 21虚拟线程 vs Kotlin协程:高并发编程模型的终极对决与选型思考
java·开发语言·kotlin
言之。2 天前
Kotlin快速入门
android·开发语言·kotlin
常利兵2 天前
Android Gradle 构建脚本现代化:Kotlin DSL (.kts) 与 Groovy DSL 深度对比与实战指南
android·开发语言·kotlin