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

相关推荐
Fate_I_C12 小时前
Android Jetpack 是什么
kotlin·android jetpack
灵感菇_1 天前
全面解析 Retrofit 网络框架
android·kotlin·网络请求·retrofit
zhangphil1 天前
Kotlin高阶函数及函数作为参数传递
kotlin
符哥20081 天前
一篇讲透掌握 Kotlin 协程
android·kotlin
芒鸽1 天前
鸿蒙应用自动化资源同步:Kuikly框架资源复制解决方案
华为·kotlin·自动化·harmonyos·kuikly
zfoo-framework2 天前
kotlin
android·开发语言·kotlin
冬奇Lab3 天前
【Kotlin系列14】编译器插件与注解处理器开发:在编译期操控Kotlin
android·开发语言·kotlin·状态模式
冬奇Lab4 天前
【Kotlin系列13】DSL设计:构建类型安全的领域语言
开发语言·安全·kotlin
MengFly_4 天前
Compose中rememberUpdatedState的作用
android·kotlin·compose