Kotlin的容器集合是在Java的基础上,进行了改造和扩展,引入了不可变集合类,同时扩展了大量方便实用的功能。
另外,在Koltin的集合类中不仅仅能持有普通对象,而且还能够持有函数类型的变量。
例如下面是一个持有两个函数的集合类:
//声明一个持有类型为 (Int)->Boolean的List,元素为两个函数
val funlist: List<(Int) -> Boolean> = listOf({ it -> it % 2 == 0 }, { it -> it % 2 ==1})
而这个时候,我们就可以在代码里面去选择调用哪个函数了
val list = listOf(1, 2, 3, 4, 5, 6, 7)
list.filter(funlist[0]) //传入第一个函数funlist[0],返回[2,4,6]
list.filter(funlist[1]) //传入第二个函数funlist[1],返回[1,3,5,7]
7.1 集合类继承层次
集合类的概述就不讲了,主要是Set、Map、List三大集合。
而他们的继承层次和Java几乎一致,但也有些不同:
这里介绍几个类:
- MutableIterable
在迭代期间支持删除元素的迭代 - Collection
只读不可写 - MutableCollection
支持添加和删除元素的Collection接口,元素有序,还有add、remove等函数 - List
元素有序,只读不可写 - MutableList
除了拥有List读数据的函数,还有add、clear、remove等写函数 - Set
只读不可写
总结
可以看出,有些集合是可写的,有些集合是不可以写的。
比如List分为只读的List
和 可读可写的MutableList
,Set也一样
而Map虽然没有继承Collection,但是它也分为 只读的 Map
,和可读可写的 MutableMap
7.2 创建集合类
Kotlin中分别使用 listOf()
、setOf()
、mapOf()
函数来创建不可变的List、Set、Map容器
使用 mutableListOf()
、mutableSetOf()
、mutableMapOf()
函数来分别创建 MutableList、MutableSet、MutableMap容器。
val list = listOf(1, 2, 3, 4, 5, 6, 7) //创建不可变list
val list1 = mutableListOf("A", "B", "C") //创建可变list
如果创建没有元素的空List,使用listOf即可,但是这个时候一定要声明参数类型:
//这样声明是会报错的
val emptyList = listOf()
//正确姿势
val emptyList<Int> = listOf()
7.3 遍历集合中的元素
List、Set类继承了Iterable接口,里面扩展了forEach函数来迭代遍历元素,Mao接口也扩展了forEach
list.forEach{
println(it)
}
set.forEach{
println(it)
}
map.forEach{
println("key = ${it.key}, value = ${it.value}")
}
另外,如果我们想在遍历元素的时候访问index下标,在List和Set中可以使用 forEachIndexed()
list.forEachIndexed { index, value -> println("list index = ${index}, value = ${value} ")
set.forEachIndexed{ index, value -> println("set index = ${index} , value = ${value}")}
}
7.4 映射函数
使用map函数,可以把集合中的元素依次使用给特定的转换函数进行映射操作,元素映射之后的新值会存入一个新的集合中,并返回这个新集合。
在List、Set继承的Iterable接口和Map接口中,都提供了这个map函数。示例如下:
val list = listOf(1, 2, 3, 4, 5, 6, 7)
val set = setOf(1, 2, 3, 4, 5, 6, 7)
val map = mapOf(1 to "a", 2 to "b", 3 to "c")
list.map{ it * it} //返回[1, 4, 9, 25, 36, 49]
set.map{ it + 1} //返回[2, 3, 4, 5, 6, 7, 8]
map.map{ it.value + "$"} //返回[a$, b$, c$]
我们可以在map中也传入的不仅仅是函数,还可以是数据类型,比如我们传入一个list:
val strList = listOf("a", "b", "c")
strlist.map{ it -> listOf(it + 1, it + 2, it + 3, it + 4) }
这个时候,返回值的类型,也就是一个List里面嵌套一个List,上面的代码返回结果如下:
//嵌套List
[[a1, a2, a3, a4], [b1, b2, b3, b4], [c1, c2, c3, c4]]
Kotlin中还提供了了一个 flatten()
,效果是把嵌套的List结构 “平铺”,变成一层的结构。代码如下:
//"平铺"函数,把嵌套在List中的元素"平铺"成一层List
strlist.map{ it -> listOf(it +1, it + 2, it +3, it +4) }.flatten()
输出如下:
[a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4]
flatMap函数时map和flat两个函数的 “复合逻辑”,代码示例如下:
strlist.flatMap { it -> listOf(it + 1, it + 2, it + 3, it + 4) }
//输出:
[a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4]
7.5 过滤函数
我们之前已经学过了 filter(),这里再举一个代码示例,首先,有一个Student对象,我们使用数据类来声明如下:
data class Student(var id:Long, var name: String, var age: Int, var score: Int){}
val studentList = listOf(
Student(1, "Java", 20, 100)
Student(2, "Kotlin", 10, 80)
Student(3, "Python", 19, 95)
)
这个时候,假如我们想过滤出年龄大于19的学生,代码可以这样写:
studentList.filter{ it.age >= 19}
如果通过访问下标来过滤,可以使用 filterIndexed()
val list = listOf(1, 2, 3, 4, 5, 6, 7)
list.filterIndexed{ index, it -> index % == 0 && it > 3}
//输出
[5, 7]
7.6 排序函数
Kotlin集合类中提供了 倒序排列集合元素的函数 reversed()
val list = listOf(1, 2, 3, 4, 5, 6, 7)
val set = setOf(1, 3, 2)
list.reversed() //倒序函数,返回[7, 6, 5, 4, 3, 2, 1]
set.reversed() //返回 (2, 3,1)
升序排序函数时 sorted()
,
list.sorted() //返回[1, 2, 3, 4, 5, 6, 7]
set.sorted() //返回[1, 2, 3]
7.7 元素去重
如果我们想对一个List列表进行元素去重,可以直接调用 distinct()
val dupList = listOf(1, 1, 2, 2, 3, 3, 3)
dupList.distinct() //返回 [1, 2, 3]