kotlin集合操作——list set map
简述
kotlin有三个集合类型——list set map,kotlin标准库提供了一整套用于管理集合的工具
这些集合接口与相关函数位于 kotlin.collections 包中
kotlin的集合分为可变集合类Mutable和不可变集合类Immutable,List、Set、Map都是不可变集合,与之对应MutableList、MutableSet、MutableMap是可变集合
创建集合
使用 listOf()、setOf()、mapOf() 创建不可变的 List、Set、Map
使用 mutableListOf()、mutableSetOf()、mutableMap() 创建可变的 MutableList 、MutableSet 、MutableMap
注意这里的to代表连接一个键值对,to前面是键,后面是值,set的默认实现是 LinkedHashSet
val list = listOf(1, 2, 3, 4, 5) val mutableList = mutableListOf("a", "b", "c") val set = setOf(1, 2, 3, 4, 5) val mutableSet = mutableSetOf("a", "b", "c") val map = mapOf(1 to "a", 2 to "b", 3 to "c") val mutableMap = mutableMapOf(1 to "X", 2 to "Y", 3 to "Z")
遍历集合
我们可以使用forEach遍历集合,其中map的遍历可通过it.key和it.value来获取键和值
list.forEach { println(it) } set.forEach { println(it) } map.forEach { println("K = ${it.key}, V = ${it.value}") }
若想在遍历的同时获取当前元素的下标,我们可以使用forEachIndexed方法
list.forEachIndexed { index, value -> println("list index = ${index}, value = $value") } set.forEachIndexed { index, value -> println("set index = ${index}, value = ${value}") }
添加元素
对于list,我们可以使用add方法添加元素,参数为一个时往list的末尾添加,两个参数时为往指定的index添加
val list = mutableListOf<Number>(1,2,3) list.add(4) list.forEach { print("$it ") // 1 2 3 4 } println() list.add(3,-1) list.forEach { print("$it ") // 1 2 3 -1 4 }
对于set,使用add方法添加元素,注意set是去重的
val set = mutableSetOf<Number>(1,2,3) set.add(4) set.forEach{ println(it) }
对于map,可以使用put方法添加,更常见的是使用中括号+等于的形式,括号内是键名,等号是值
val map = mutableMapOf<Number,String>(1 to "a",2 to "b") //map.put(3,"c") map[3]="c" map.forEach{ println("${it.key} ${it.value}") }
删除元素
list使用remove(value)删除值为value的元素,使用removeAt(index)删除指定下标元素
removeFirst()和removeLast()删除第一个和最后一个元素
val list = mutableListOf<Number>(10, 20, 30, 40, 50, 60, 70) list.remove(10) // 20, 30, 40, 50, 60, 70 list.removeAt(2) // 20, 30, 50, 60, 70 list.removeFirst() // 30, 50, 60, 70 list.removeLast() // 30, 50, 60
set的remove删除指定值的元素
val set = mutableSetOf<Number>(10, 20, 30, 40) set.remove(20) // 10 30 40
map使用remove删除元素,remove传入想删除的键值
val map = mutableMapOf<Number,String>(1 to "a",2 to "b") map.remove(2) map.forEach{ println("${it.key} ${it.value}") // 1 a }
list集合相关操作
按索引取元素
list本质就可以理解为一个变长数组,最简单的就是像数组一样通过[]拿到值
val numbers = listOf(1, 2, 3, 4) println(numbers.get(0)) println(numbers[0]) //numbers.get(5) // exception! println(numbers.getOrNull(5)) // null println(numbers.getOrElse(5, {it})) // 5
取列表的一部分
使用subList可以指定左闭右开的区间,取出list的一部分
val numbers = (0..13).toList()
println(numbers.subList(3, 6))
排序
对于普通的基本类型,可以直接调用sort()和sortDescending()进行升序和降序排列
val list = mutableListOf(5,4,1,2,3,7,10) list.sort() //按升序排序 list.sortDescending() //降序
sort()和sortDescending()加上ed变成sorted()和sortedDescending()则是返回一个全新的排序后的list,原来的list不变
我们还可以使用sortBy()方法进行排序,例如这里我们对Student类的age属性进行生序排序
sortBy是以值的自然顺序进行排序,Int、Double、String等都都定义好的自然顺序
data class Student( val age: Int, val name: String, ) fun main() { val students = mutableListOf<Student>( Student(12, "c"), Student(19, "b"), Student(15, "a") ) students.sortBy { x -> x.age } students.forEach(::println) }
同理sortByDescending是根据降序的自然顺序排序
sortWith
查看sortBy的源码我们可以看到内部调用的是sortWith,sortWith常用于根据不同条件进行排序
sortWith需要传入一个比较器Comparator参数,我们可以用compareBy生成自己想要的比较器
compareBy里面靠左的优先级高,默认是升序排序,例如这里我们先通过age升序排序,age相同时根据name升序排序
data class Student( val age: Int, val name: String, ) fun main() { val students = mutableListOf<Student>( Student(12, "c"), Student(19, "b"), Student(19, "a"), Student(15, "a"), ) students.sortWith(compareBy({ it.age }, { it.name })) students.forEach(::println) }
如果需要先a属性升序,再b属性降序排序,则在生成的comparator后使用thenByDescending指定属性进行降序排序
data class Student( val age: Int, val name: String, ) fun main() { val students = mutableListOf<Student>( Student(12, "c"), Student(19, "b"), Student(19, "a"), Student(15, "a"), ) students.sortWith(compareBy<Student> { it.age } .thenByDescending { it.name }) students.forEach(::println) }
同理可以无限套娃下去,这里的例子是先根据age升序,再根据name降序,再根据bAge升序
data class Student( val age: Int, val name: String, val bAge: Int, ) fun main() { val students = mutableListOf<Student>( Student(12, "c",5), Student(19, "b",3), Student(19, "a",4), Student(19, "a",2), Student(15, "a",2), ) students.sortWith(compareBy<Student> { it.age }.thenByDescending { it.name }.thenBy { it.bAge }) students.forEach(::println) }
GroupBy转map
对于一个对象list,我们可以根据对象的属性将list分组,和数据库的groupBy类似
例如我们这里有一个student的list
val students = mutableListOf<Student>( Student(1, "xiaoming", "guangzhou"), Student(2, "xiaohong", "shenzhen"), Student(2, "xiaohong2", "shenzhen"), Student(2, "xiaohong3", "chongqing"), Student(3, "xiaohei", "xian"), Student(3, "xiaohei2", "shenzhen"), )
然后我们可以通过student的age进行分组,分组后list会变成一个map,key是我们分组的属性,value是一个list,装着所有符合该分组条件的元素
val afterGroupBy = students.groupBy { it.age }
afterGroupBy.forEach { println("${it.key} ${it.value}") }
groupBy里实际上可以放任何数据类型,它的目的就是将list分组转化成map
例如下面我们以一个age to name的pair作为groupBy的条件
val students = mutableListOf<Student>( Student(1, "xiaoming", "guangzhou"), Student(2, "xiaohong2", "shenzhen"), Student(2, "xiaohong3", "chongqing"), Student(2, "xiaohong3", "chongqing"), Student(3, "xiaohei", "xian"), Student(3, "xiaohei2", "shenzhen"), ) val afterGroupBy = students.groupBy { it.age to it.name } afterGroupBy.forEach { println("${it.key} ${it.value}") }
我们可以看到age为2,name为xiaohong3到student被groupBy起来了
map集合相关操作
mapValues
对于一个map,我们可以将它的value进行一个映射
例如这里有一个有一个Int到String的map,我们对这个map进行mapValues的操作
val map = mutableMapOf<Int,String>(1 to "a",2 to "b")
val map2 = map.mapValues { entry -> entry.value + "abc" }
操作完map2里的value就是map里value拼接上abc的值
References
https://www.kotlincn.net/docs/reference/collections-overview.html
https://juejin.cn/post/6957922140767125517
https://www.kotlincn.net/docs/reference/collection-ordering.html
https://developer.android.com/codelabs/basic-android-kotlin-compose-collections?hl=zh-tw#0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2021-03-09 Filter过滤器