Kotlin 语言参考文档 中文版 Help

创建集合

通过指定的元素创建

创建集合最常用的方法是使用标准库中的函数 listOf<T>(), setOf<T>(), mutableListOf<T>(), mutableSetOf<T>(). 如果使用逗号分隔的一系列集合元素作为这些函数的参数, 编译器会自动判定元素类型. 如果要创建空的集合, 就无法从参数推断元素类型, 因此需要明确指定元素类型.

val numbersSet = setOf("one", "two", "three", "four") val emptySet = mutableSetOf<String>()

创建 map 的方法类似, 使用的函数是 mapOf()mutableMapOf(). map 的键(key) 和值(value) 通过 Pair 对象传递给函数 (通常使用中缀函数 to 来创建 键(key) 和值(value) 的 Pair 对象).

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)

注意, 使用 to 这样的写法创建的是短期存在的 Pair 对象, 因此只有在性能问题不严重的情况下才推荐这种写法. 为避免消耗过多的内存, 可以使用其他方法. 比如, 可以创建可变的 map, 然后通过写操作向其中填充数据. 这种情况下使用 apply() 函数可以让 map 的初始化过程更加流畅.

val numbersMap = mutableMapOf<String, String>().apply { this["one"] = "1"; this["two"] = "2" }

使用集合构建函数来创建

创建集合的另一种方法是调用构建函数 – buildList(), buildSet(), 和 buildMap(). 这些函数创建新的, 可变的集合, 然后使用 写操作填充集合内容, 再返回一个只读的集合, 包含相同的元素:

val map = buildMap { // 在这里是 MutableMap<String, Int>, key 和 value 的类型通过下面的 `put()` 调用推断得到 put("a", 1) put("b", 0) put("c", 4) } println(map) // {a=1, b=0, c=4}

创建空集合

还有一些函数可以用来创建不包含元素的空集合: emptyList(), emptySet(), 以及 emptyMap(). 创建空集合时, 你需要明确指定集合中存储的元素的数据类型.

val empty = emptyList<String>()

使用 list 的初始化函数

对于 list, 有一个类似构造器的函数, 它接受的参数是 list 大小, 以及一个初始化函数, 这个初始化函数负责根据元素的下标计算各个元素的值.

fun main() { //sampleStart val doubled = List(3, { it * 2 }) // 如果希望将来改变其中的值, 可以使用 MutableList println(doubled) //sampleEnd }

使用具体类型的(Concrete type) 集合构造器

如果希望创建一个具体类型(concrete type)的集合, 比如 ArrayListLinkedList, 可以使用这些集合类型的构造器. SetMap 的实现类也有类似的构造器.

val linkedList = LinkedList<String>(listOf("one", "two", "three")) val presizedSet = HashSet<Int>(32)

从既有的集合复制

如果想要从已有的集合创建一个相同内容的新集合, 可以使用复制(copy)函数. 标准库中提供的集合复制函数创建的是 浅(shallow) 复制的集合, 其中的元素与既有的集合指向相同的对象引用. 因此, 对集合中某个元素进行修改, 会反映到这个元素的所有副本.

集合复制函数, 比如 toList(), toMutableList(), toSet() 等等, 会创建一个集合在函数调用那一刻的副本(snapshot). 这些函数的结果是一个新的集合, 但包含完全相同的元素. 如果对原来的集合添加或删除元素, 不会影响到副本集合中的内容. 同样的, 对副本的修改也不会影响到原来的集合.

class Person(var name: String) fun main() { //sampleStart 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") //sampleEnd }

这些函数也可以用来将一个集合转换为其他类型的集合, 比如从一个 list 创建一个 set, 或者相反.

fun main() { //sampleStart val sourceList = mutableListOf(1, 2, 3) val copySet = sourceList.toMutableSet() copySet.add(3) copySet.add(4) println(copySet) //sampleEnd }

另一种方法是, 你可以创建一个新的引用, 指向相同的集合实例. 如果用一个既有的集合初始化赋值给一个集合变量, 这时就创建了一个新的引用. 这种情况下, 如果通过一个引用修改了集合实例的内容, 这些变化会影响到所有其他的引用.

fun main() { //sampleStart val sourceList = mutableListOf(1, 2, 3) val referenceList = sourceList referenceList.add(4) println("Source size: ${sourceList.size}") //sampleEnd }

集合的初始化可以用来限制它的可变性. 比如, 如果创建一个 List 引用, 指向一个 MutableList, 那么如果你当你想要使用这个只读类型的 List 引用来修改集合内容, 编译器会报告编译错误.

fun main() { //sampleStart val sourceList = mutableListOf(1, 2, 3) val referenceList: List<Int> = sourceList //referenceList.add(4) // 编译错误 sourceList.add(4) println(referenceList) // 显示 sourceList 的当前状态 //sampleEnd }

调用其他集合的函数

在既有的集合上执行各种操作的结果也可以创建新的集合. 比如, 过滤(filtering) 一个 list 会创建一个新的 list, 其中只包含满足过滤条件的元素:

fun main() { //sampleStart val numbers = listOf("one", "two", "three", "four") val longerThan3 = numbers.filter { it.length > 3 } println(longerThan3) //sampleEnd }

映射(Mapping) 函数会创建一个新的 list, 其中包含各个元素变换后的结果:

fun main() { //sampleStart val numbers = setOf(1, 2, 3) println(numbers.map { it * 3 }) println(numbers.mapIndexed { idx, value -> value * idx }) //sampleEnd }

关联(Association) 函数会创建 map:

fun main() { //sampleStart val numbers = listOf("one", "two", "three", "four") println(numbers.associateWith { it.length }) //sampleEnd }

关于 Kotlin 集合的各种操作, 详情请参见 集合的各种操作(Operation)概述.

最终更新: 2024/10/17