9.1.1.2 构造集合
原文链接: https://kotlinlang.org/docs/constructing-collections.html
9.1.1.2 构造集合
由元素构造
创建集合最常见的方式是使用标准库函数 listOf<T>()、setOf<T>()、mutableListOf<T>()、mutableSetOf<T>()。如果你以逗号分隔的集合元素列表作为实参传入,编译器会自动推断元素类型。创建空集合时,请显式指定类型。
1
2
| val numbersSet = setOf("one", "two", "three", "four")
val emptySet = mutableSetOf<String>()
|
映射也有对应的函数 mapOf() 和 mutableMapOf()。映射的键和值以 Pair 对象的形式传入(通常使用 to 中缀函数创建)。
1
| val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)
|
请注意,to 写法会创建一个短生命周期的 Pair 对象,因此只有在对性能要求不高时才建议使用它。为避免过多的内存占用,请使用其他方式。例如,你可以创建一个可变映射,然后用写操作填充它。apply() 函数在这里可以帮助你保持初始化过程的流畅书写。
1
| val numbersMap = mutableMapOf<String, String>().apply { this["one"] = "1"; this["two"] = "2" }
|
使用集合构建器函数创建
创建集合的另一种方式是调用构建器函数——buildList()、buildSet() 或 buildMap()。它们会创建相应类型的新可变集合,使用写操作填充它,并返回包含相同元素的只读集合:
1
2
3
4
5
6
7
| val map = buildMap { // 这是 MutableMap<String, Int>,键和值的类型根据下面的 `put()` 调用推断
put("a", 1)
put("b", 0)
put("c", 4)
}
println(map) // {a=1, b=0, c=4}
|
空集合
还有一些用于创建不含任何元素的集合的函数:emptyList()、emptySet() 和 emptyMap()。创建空集合时,应指定集合将要保存的元素类型。
1
| val empty = emptyList<String>()
|
列表的初始化函数
对于列表,有一个类似构造器的函数,它接收列表大小以及一个根据索引定义元素值的初始化函数。
1
2
3
4
| fun main() {
val doubled = List(3, { it * 2 }) // 如果你以后想修改其内容,也可以使用 MutableList
println(doubled)
}
|
具体类型构造器
要创建具体类型的集合,例如 ArrayList 或 LinkedList,你可以使用这些类型已有的构造器。Set 和 Map 的实现也有类似的构造器。
1
2
| val linkedList = LinkedList<String>(listOf("one", "two", "three"))
val presizedSet = HashSet<Int>(32)
|
复制
要创建一个与现有集合元素相同的集合,你可以使用复制函数。标准库中的集合复制函数会创建浅拷贝集合,其中的引用指向相同的元素。因此,对某个集合元素所做的修改会反映在它的所有副本中。
集合复制函数,例如 toList()、toMutableList()、toSet() 等,会创建某个集合在特定时刻的快照。它们的结果是包含相同元素的新集合。如果你在原始集合中添加或移除元素,不会影响这些副本。副本也可以独立于源集合进行修改。
1
2
3
4
5
6
7
8
9
10
| class Person(var name: String)
fun main() {
val alice = Person("Alice")
val sourceList = mutableListOf(alice, Person("Bob"))
val copyList = sourceList.toList()
sourceList.add(Person("Charles"))
alice.name = "Alicia"
println("First item's name is: ${sourceList[0].name} in source and ${copyList[0].name} in copy")
println("List size is: ${sourceList.size} in source and ${copyList.size} in copy")
}
|
这些函数还可以用于把集合转换为其他类型,例如从列表构建集合,或者反过来。
1
2
3
4
5
6
7
| fun main() {
val sourceList = mutableListOf(1, 2, 3)
val copySet = sourceList.toMutableSet()
copySet.add(3)
copySet.add(4)
println(copySet)
}
|
另一种方式是创建指向同一个集合实例的新引用。当你用现有集合初始化一个集合变量时,就会创建新的引用。因此,当通过某个引用修改集合实例时,改动会反映在它的所有引用中。
1
2
3
4
5
6
| fun main() {
val sourceList = mutableListOf(1, 2, 3)
val referenceList = sourceList
referenceList.add(4)
println("Source size: ${sourceList.size}")
}
|
集合的初始化方式可以用来限制可变性。例如,如果你创建了一个指向 MutableList 的 List 引用,那么当你尝试通过该引用修改集合时,编译器会报错。
1
2
3
4
5
6
7
| fun main() {
val sourceList = mutableListOf(1, 2, 3)
val referenceList: List<Int> = sourceList
//referenceList.add(4) //编译错误
sourceList.add(4)
println(referenceList) // 显示 sourceList 的当前状态
}
|
在其他集合上调用函数
集合也可以作为对其他集合执行各种操作的结果而被创建。例如,对列表进行过滤会创建一个包含符合过滤条件元素的新列表:
1
2
3
4
5
| fun main() {
val numbers = listOf("one", "two", "three", "four")
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3)
}
|
映射(map)会基于转换结果生成一个列表:
1
2
3
4
5
| fun main() {
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 })
println(numbers.mapIndexed { idx, value -> value * idx })
}
|
关联(associate)会生成映射:
1
2
3
4
| fun main() {
val numbers = listOf("one", "two", "three", "four")
println(numbers.associateWith { it.length })
}
|
关于 Kotlin 中集合操作的更多信息,请参阅集合操作概览。