构造集合

由元素构造

创建集合的最常用方法是使用标准库函数 listOf()setOf()mutableListOf()mutableSetOf()。 如果以逗号分隔的集合元素列表作为参数,编译器会自动检测元素类型。创建空集合时,须明确指定类型。

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

同样的,Map 也有这样的函数 mapOf()mutableMapOf()。映射的键和值作为 Pair 对象传递(通常使用中缀函数 to 创建)。

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

注意,to 符号创建了一个短时存活的 Pair 对象,因此建议仅在性能不重要时才使用它。 为避免过多的内存使用,请使用其他方法。例如,可以创建可写 Map 并使用写入操作填充它。 apply() 函数可以帮助保持初始化流畅。

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

Create with collection builder functions

Another way of creating a collection is to call a builder function – buildList(), buildSet(), or buildMap(). They create a new, mutable collection of the corresponding type, populate it using write operations, and return a read-only collection with the same elements:

  1. val map = buildMap { // this is MutableMap<String, Int>, types of key and value are inferred from the `put()` calls below
  2. put("a", 1)
  3. put("b", 0)
  4. put("c", 4)
  5. }
  6. println(map) // {a=1, b=0, c=4}

空集合

还有用于创建没有任何元素的集合的函数:emptyList()emptySet()emptyMap()。 创建空集合时,应指定集合将包含的元素类型。

  1. val empty = emptyList<String>()

list 的初始化函数

对于 List,有一个接受 List 的大小与初始化函数的类似构造函数的函数,该初始化函数根据索引定义元素的值。

  1. fun main() {
  2. //sampleStart
  3. val doubled = List(3, { it * 2 }) // 如果你想操作这个集合,应使用 MutableList
  4. println(doubled)
  5. //sampleEnd
  6. }

具体类型构造函数

要创建具体类型的集合,例如 ArrayListLinkedList,可以使用这些类型的构造函数。 类似的构造函数对于 SetMap 的各实现中均有提供。

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

复制

要创建与现有集合具有相同元素的集合,可以使用复制函数。 标准库中的集合复制函数创建了具有相同元素引用的 复制集合。 因此,对集合元素所做的更改会反映在其所有副本中。

在特定时刻通过集合复制函数,例如toList()toMutableList()toSet() 等等。create a snapshot of a collection at a specific moment. 结果是创建了一个具有相同元素的新集合 如果在源代码集合中添加或删除元素,则不会影响副本。副本也可以独立于源代码集合进行更改。

  1. class Person(var name: String)
  2. fun main() {
  3. //sampleStart
  4. val alice = Person("Alice")
  5. val sourceList = mutableListOf(alice, Person("Bob"))
  6. val copyList = sourceList.toList()
  7. sourceList.add(Person("Charles"))
  8. alice.name = "Alicia"
  9. println("First item's name is: ${sourceList[0].name} in source and ${copyList[0].name} in copy")
  10. println("List size is: ${sourceList.size} in source and ${copyList.size} in copy")
  11. //sampleEnd
  12. }

这些函数还可用于将集合转换为其他类型,例如根据 List 构建 Set,反之亦然。

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

或者,可以创建对同一集合实例的新引用。使用现有集合初始化集合变量时,将创建新引用。 因此,当通过引用更改集合实例时,更改将反映在其所有引用中。

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

集合的初始化可用于限制其可变性。例如,如果构建了一个 MutableListList 引用,当你试图通过此引用修改集合的时候,编译器会抛出错误。

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

调用其他集合的函数

可以通过其他集合各种操作的结果来创建集合。例如,过滤列表会创建与过滤器匹配的新元素列表:

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

映射由转换结果生成列表:

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

关联生成 Map:

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

关于 Kotlin 中集合操作的更多信息,参见集合操作概述.