0%

Kotlin Basic Chapter Four

Kotlin学习笔记

数组和集合

数组

1
2
val strs: Array<String> = arrayOf("a", "b", "c")
val intArray = intArrayOf(1, 2, 3)

可以看到 Kotlin 中的数组是一个拥有泛型的类
将数组泛型化有什么好处呢?对数组的操作可以像集合一样功能更强大,由于泛型化,Kotlin 可以给数组增加很多有用的工具函数:

  • get() / set()
  • contains()
  • first()
  • find()
    这样数组的实用性就大大增加了。

    取值和修改

    Kotlin 中获取或者设置数组元素和 Java 一样,可以使用方括号加下标的方式索引:
    1
    2
    println(strs[0])
    strs[1] = "B"

不支持协变

Kotlin 的数组编译成字节码时使用的仍然是 Java 的数组,但在语言层面是泛型实现,这样会失去协变 (covariance) 特性,就是子类数组对象不能赋值给父类的数组变量:

1
2
val strs: Array<String> = arrayOf("a", "b", "c")
val anys: Array<Any> = strs // compile-error: Type mismatch

集合

Kotlin 和 Java 一样有三种集合类型:List、Set 和 Map,它们的含义分别如下:

  • List 以固定顺序存储一组元素,元素可以重复。

    1
    2
    val strList = listOf("a", "b", "c")
    val strList1 = listOf("a", "b", "c")
  • Set 存储一组互不相等的元素,通常没有固定顺序。

    1
    val strSet = setOf("a", "b", "c")
  • Map 存储 键-值 对的数据集合,键互不相等,但不同的键可以对应相同的值。

    1
    2
    3
    4
    5
    6
    7
    val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 3)
    //get() 根据键获取对应的值,还可以使用方括号的方式获取
    val value1 = map.get("key1")
    val value2 = map["key2"]
    //用方括号的方式改变 Map 中键对应的值
    map.put("key1", 2)
    map["key1"] = 2

可变集合/不可变集合

上面修改 Map 值的例子中,创建函数用的是 mutableMapOf() 而不是 mapOf(),因为只有 mutableMapOf() 创建的 Map 才可以修改。Kotlin 中集合分为两种类型:只读的和可变的。这里的只读有两层意思:
集合的 size 不可变
集合中的元素值不可变
以下是三种集合类型创建不可变和可变实例的例子:
listOf() 创建不可变的 List,mutableListOf() 创建可变的 List。
setOf() 创建不可变的 Set,mutableSetOf() 创建可变的 Set。
mapOf() 创建不可变的 Map,mutableMapOf() 创建可变的 Map。

1
2
3
4
5
6
7
8
9
val strList = listOf("a", "b", "c")
//不可变的可以通过 toMutable*() 系函数转换成可变的集合
strList.toMutableList()

val strSet = setOf("a", "b", "c")
strSet.toMutableSet()

val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 3)
map.toMutableMap()

Sequence

Kotlin引入了一个新的容器类型 Sequence,它和 Iterable 一样用来遍历一组数据并可以对每个元素进行特定的处理,先来看看如何创建一个 Sequence

1
2
3
4
5
6
7
8
sequenceOf("a", "b", "c")

val list = listOf("a", "b", "c")
list.asSequence()

//使用 lambda 表达式创建
val sequence = generateSequence(0) { it + 1 }
//lambda 表达式,负责生成第二个及以后的元素,it 表示前一个元素

Sequence 又被称为「惰性集合操作」

1
2
3
4
5
6
7
8
9
10
11
12
val sequence = sequenceOf(1, 2, 3, 4)
val result: List = sequence
.map { i ->
println("Map $i")
i * 2
}
.filter { i ->
println("Filter $i")
i % 3 == 0
}
println(result.first()) // 只取集合的第一个元素
//惰性指当出现满足条件的第一个元素的时候,Sequence 就不会执行后面的元素遍历了,即跳过了 4 的遍历。

Range

Range 表示区间的意思,也就是范围,IntRange、CharRange以及LongRange

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//闭区间 [0, 1000]
val range: IntRange = 0..1000
for (i in range) {
print("$i, ")
}
//步长为 2
for (i in range step 2) {
print("$i, ")
}
//递减区间
for (i in 4 downTo 1) {
print("$i, ")
}

//半开区间 [0, 1000)
val range: IntRange = 0 until 1000

数组与集合的操作符

  • forEach:遍历每一个元素

    1
    2
    3
    4
    //lambda 表达式遍历数组,i 表示数组的每个元素
    intArray.forEach { i ->
    print(i + " ")
    }
  • filter:对每个元素进行过滤操作

    1
    2
    3
    val newList: List = intArray.filter { i ->
    i != 1 // 过滤掉数组中等于 1 的元素
    }
  • map:遍历每个元素并执行给定表达式,最终形成新的集合

    1
    2
    3
    val newList: List = intArray.map { i ->
    i + 1 // 每个元素加 1
    }
  • flatMap:遍历每个元素,并为每个元素创建新的集合,最后合并到一个集合中

    1
    2
    3
    intArray.flatMap { i ->
    listOf("${i + 1}", "a") // 生成新集合
    }
如果你觉得有用,可以请我喝杯茶