集合可以方便你处理一组数据,也可以作为值参传给函数,和我们学过的其它变量类型一样,List、Set 和 Map 类型的变量也分为两类,只读和可变。
List创建与元素获取
通过 listOf() 函数创建一个 List 集合。
val listString : List = listOf("HL", "HYM", "HMY")
val listInt = listOf(1, 2, 3, 5)
在 kt 中获取 List 中的元素和 java 一样,listInt[index] 就可以获取 index 位置的元素。
通过索引获取 List 中的元素,那么就会存在 ArrayIndexOutOfBoundsException 异常。如下所示
fun main() {
val listInt = listOf(1, 2, 3, 5)
System.out.println(listInt[4]) // 显然 List 里没有索引为 4 的元素
}
对于这种情况,在 kotlin 里面提供了很多安全函数,来避免异常索引。
getOrElse:getOrElse 是一个安全索引取值函数,它需要两个参数,第一个是索引值,第二个是能提供默认值的 lambda 表达式,如果索引值不存在的话,可以用来 lambda 的默认值来替异常。
示例:
getOrNull:getOrNull 是 Kotlin 提供的另一个安全索引取值函数,它返回 null 结果,而不是抛出异常。
示例:
通过这两种方法,当我们不小心索引越界时,就不会抛出异常。
可变列表
在 Kotlin 中,支持内容修改的列表叫可变列表。要创建可变列表,可以使用 mutableListOf 函数。List。List 还支持使用 toList 和 toMutableList 函数,动态实现只读列表和可变列表的相互转换。
示例:创建可变 List,添加和删除元素。
fun main() {
// MutableList
val mutableIntList = mutableListOf(1, 2, 3, 4)
mutableIntList.add(5)
mutableIntList.remove(3) // 根据元素值移除
mutableIntList.removeAt(0) // 根据索引移除
}
示例:MutableList 和 List 互转
listOf(1, 2, 3).toMutableList()
mutableListOf(1, 2, 3).toList()
mutator 函数
能修改可变列表的函数有一个统一的名字:mutator 函数。比如上面的add()、remove() 函数以及后面的 removeIf() 函数等。
添加元素运算符与删除元素运算符
val mutableStringList = mutableListOf("jack", "bob", "jason")
mutableStringList += "Jimmy" // 与 add() 相同
mutableStringList -= "jack" // 与 remove() 相同
println(mutableStringList)
基于 lambda 表达式指定的条件删除元素。removeIf() 函数。
val mutableStringList = mutableListOf("jack", "bob", "jason")
mutableStringList += "Jimmy" // 与 add() 相同
mutableStringList -= "jack" // 与 remove() 相同
mutableStringList.removeIf { it.contains("jason") } // 如果包含 jason,则将其移除
println(mutableStringList)
List 集合遍历
for in 遍历
示例:
val list = listOf(3, 2, 5, 1)
for (i in list) {
print("$i, ")
}
forEach 遍历
list.forEach {
print(it)
}
forEachIndexed 遍历时要获取索引值
list.forEachIndexed{index, element ->
println("$index, $element")
}
解构语法过滤元素
通过"_"符号过滤不想要的元素
// 这种写法,可以把 list 里的每个元素赋值给等号前面()里的变量
val (one, two ,three) = listOf(3, 2, 1)
// 有时我们不需要给()里的每个元素都赋值,而是给几个赋值。TODO 那么不需要赋值的变量就要 _ 代替
val (a, _ ,c) = listOf(3, 2, 1)
解释说明:第二行代码中,我们不想给第二个变量赋值,则用 _ 来代替。
Set 创建与元素获取
通过 setOf 创建 set 集合,使用 elementAt 函数读取集合中的元素。
示例:set 取元素时也有 安全索引取值函数
fun main() {
val intSet = setOf(1, 2, 3)
intSet.forEach {
print("$it, ")
}
// 取元素
intSet.elementAt(1)
// 取元素时也有 TODO 安全索引取值函数
intSet.elementAtOrElse(4){"Unknown"}
intSet.elementAtOrNull(3) ?: "Unknown" // 这里还可以和 空合并操作符 一起使用
}
可变 Set 集合
通过 mutableSetOf 创建可变的 set 集合。可变的操作与 List 是一样的。
示例:
val mutableSet = mutableSetOf(1, 2, 3)
mutableSet.add(4)
mutableSet -= 3
集合转换与快捷函数
Set 和 List 是可以相互转换的。通过把 List 转换成 Set,去掉重复元素。
fun main() {
val listName = listOf("jack", "bob", "lily", "jack")
.toSet() // 先转为 set 去重
.toList() // 再由 set 转回 list
println(listName)
}
快捷函数。
上面方法的先 toSet() 然后再 toList 有点太麻烦了,kotlin 给我们提供了一个快捷函数 distinct(),直接一步搞定。
val distinct : List = listOf("jack", "bob", "lily", "jack").distinct()
println(distinct)
注意:set 和 list 的区别是,list 中的元素可以重复,而 Set 中的元素是不重复的。即使往 set 集合中方重复的元素,set 会通过覆盖的方式来避免重复。
数组类型
Kotlin 提供各自 Array,虽然是引用类型,但可以编译成 Java 基本数据类型。
示例:
// 创建 Int 类型数组
val intArray : IntArray = intArrayOf(10, 13, 131)
// list 也可以直接转为数组
listOf(1, 2, 3).toIntArray()
// 创建对象数组
val array : Array = arrayOf(File("D://xx.txt"), File("D://yy.txt"))
Map 集合
Map 的创建和 List、Set 不同,因为 Map 是键值对的形式,有 key 和 value。和 java 创建 map 也不一样,kotlin 中会用到 to。to 看上去像关键字,但事实上,它是个省略了点号和参数的特殊函数,to 函数将它左边和右边的值转化成一对 Pair。所以也可以直接调用 Pair() 函数。
示例:mapOf() 函数
// Map 创建
mapOf("Jack" to 12, "Bob" to 12, "lily" to 13)
mapOf(Pair("Jack", 12), Pair("Bob", 12), Pair("Lily", 13))
读取 Map 的值
[] 取值运算符,读取键对应的值,如果键不存在就返回 null;
val map = mapOf("Jack" to 12, "Bob" to 12, "lily" to 13)
println(map["jack"])
getValue,读取键对应的值,如果键不存在就抛出异常;
val map = mapOf("Jack" to 12, "Bob" to 12, "lily" to 13)
println(map.getValue("Bob"))
getOrElse,读取键对应的值,或者使用匿名函数返回默认值;
val map = mapOf("Jack" to 12, "Bob" to 12, "lily" to 13)
println(map.getOrElse("Rose"){"Unknown"})
如果没有"Rose" 就返回 {}(匿名函数)里的内容
getOrDefault,读取键对应的值,或者返回默认值。
val map = mapOf("Jack" to 12, "Bob" to 12, "lily" to 13)
println(map.getOrDefault("lilys", 0))
遍历 Map
forEach 遍历 Map。
可变 Map 集合
通过 mutableMapOf 创建可变 Map;
val mutableMap = mutableMapOf("Jack" to 12, "Bob" to 12, "lily" to 13)
mutableMap += "HL" to 17
mutableMap.put("HYM", 18)
getOrPut 键值不存在,就添加并返回结果,否则就返回已有键对应的值。
// 如果没有 key 为 XY,那么就放入该键值对,如果有,则获取该键值对
mutableMap.getOrPut("XY"){19}