集合
编程时,将数据分组到结构中以便后续处理是非常有用的。Kotlin 正为此目的提供了集合。
Kotlin 提供了以下集合类型来分组项目:
集合类型 | 描述 |
---|---|
Lists | 有序的项目集合 |
Sets | 唯一的无序项目集合 |
Maps | 键值对的集合,其中键是唯一的且只映射到一个值 |
每种集合类型都可以是可变的或只读的。
List
Lists 按照添加的顺序存储项目,并允许重复项目。
要创建只读 list (List
),请使用 listOf()
函数。
要创建可变 list (MutableList
), 请使用 mutableListOf()
函数。
创建 list 时,Kotlin 可以推断所存储项目的类型。要显式声明类型,请在 list 声明后将类型添加到尖括号 <>
内:
fun main() {
// Read only list
val readOnlyShapes = listOf("triangle", "square", "circle")
println(readOnlyShapes)
// [triangle, square, circle]
// Mutable list with explicit type declaration
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
println(shapes)
// [triangle, square, circle]
}
为了防止不必要的修改,你可以通过将可变 list 赋值给
List
来创建它的只读视图:kotlinval shapes: MutableList<String> = mutableListOf("triangle", "square", "circle") val shapesLocked: List<String> = shapes
这也被称为 类型转换 (casting)。
Lists 是有序的,因此要访问 list 中的项目,请使用索引访问操作符 []
:
fun main() {
val readOnlyShapes = listOf("triangle", "square", "circle")
println("The first item in the list is: ${readOnlyShapes[0]}")
// The first item in the list is: triangle
}
要获取 list 中的第一个或最后一个项目,请分别使用 .first()
和 .last()
函数:
fun main() {
val readOnlyShapes = listOf("triangle", "square", "circle")
println("The first item in the list is: ${readOnlyShapes.first()}")
// The first item in the list is: triangle
}
.first()
和.last()
函数是扩展函数的示例。要在对象上调用扩展函数,请在对象名称后加上句点.
,然后是函数名。扩展函数在中级教程中有详细介绍。 目前,你只需了解如何调用它们。
要获取 list 中的项目数量,请使用 .count()
函数:
fun main() {
val readOnlyShapes = listOf("triangle", "square", "circle")
println("This list has ${readOnlyShapes.count()} items")
// This list has 3 items
}
要检测项目是否在 list 中,请使用 in
操作符:
fun main() {
val readOnlyShapes = listOf("triangle", "square", "circle")
println("circle" in readOnlyShapes)
// true
}
要从可变 list 中添加或移除项目,请分别使用 .add()
和 .remove()
函数:
fun main() {
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
// Add "pentagon" to the list
shapes.add("pentagon")
println(shapes)
// [triangle, square, circle, pentagon]
// Remove the first "pentagon" from the list
shapes.remove("pentagon")
println(shapes)
// [triangle, square, circle]
}
Set
List 是有序并允许重复项目,而 Set 则是无序的,并且只存储唯一的项目。
要创建只读 set (Set
),请使用 setOf()
函数。
要创建可变 set (MutableSet
), 请使用 mutableSetOf()
函数。
创建 set 时,Kotlin 可以推断所存储项目的类型。要显式声明类型,请在 set 声明后将类型添加到尖括号 <>
内:
fun main() {
// Read-only set
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
// Mutable set with explicit type declaration
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")
println(readOnlyFruit)
// [apple, banana, cherry]
}
在前面的示例中可以看到,因为 Set 只包含唯一元素,所以重复的 "cherry"
项目被去掉了。
为了防止不必要的修改,你可以通过将可变 set 赋值给
Set
来创建它的只读视图:kotlinval fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry") val fruitLocked: Set<String> = fruit
由于 Set 是无序的,因此无法通过特定索引访问项目。
要获取 set 中的项目数量,请使用 .count()
函数:
fun main() {
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
println("This set has ${readOnlyFruit.count()} items")
// This set has 3 items
}
要检测项目是否在 set 中,请使用 in
操作符:
fun main() {
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
println("banana" in readOnlyFruit)
// true
}
要从可变 set 中添加或移除项目,请分别使用 .add()
和 .remove()
函数:
fun main() {
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")
fruit.add("dragonfruit") // Add "dragonfruit" to the set
println(fruit) // [apple, banana, cherry, dragonfruit]
fruit.remove("dragonfruit") // Remove "dragonfruit" from the set
println(fruit) // [apple, banana, cherry]
}
Map
Maps 将项目存储为键值对。通过引用键来访问值。你可以将 map 想象成一个食物菜单。 你可以通过查找你想要吃的食物(键)来找到价格(值)。如果你想在不使用编号索引的情况下查找值,例如在 list 中,Map 非常有用。
- Map 中的每个键都必须是唯一的,以便 Kotlin 能够理解你想要获取哪个值。
- Map 中可以有重复的值。
要创建只读 map (Map
),请使用 mapOf()
函数。
要创建可变 map (MutableMap
), 请使用 mutableMapOf()
函数。
创建 map 时,Kotlin 可以推断所存储项目的类型。要显式声明类型,请在 map 声明后将键和值的类型添加到尖括号 <>
内。例如:MutableMap<String, Int>
。 键的类型为 String
,值的类型为 Int
。
创建 map 最简单的方法是在每个键及其相关值之间使用 to
:
fun main() {
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(readOnlyJuiceMenu)
// {apple=100, kiwi=190, orange=100}
// Mutable map with explicit type declaration
val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(juiceMenu)
// {apple=100, kiwi=190, orange=100}
}
为了防止不必要的修改,你可以通过将可变 map 赋值给
Map
来创建它的只读视图:kotlinval juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100) val juiceMenuLocked: Map<String, Int> = juiceMenu
要访问 map 中的值,请使用带其键的索引访问操作符 []
:
fun main() {
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println("The value of apple juice is: ${readOnlyJuiceMenu["apple"]}")
// The value of apple juice is: 100
}
如果你尝试使用 map 中不存在的键来访问键值对,你将看到
null
值:kotlinfun main() { // Read-only map val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100) println("The value of pineapple juice is: ${readOnlyJuiceMenu["pineapple"]}") // The value of pineapple juice is: null }
本教程稍后将在空安全章节中解释 null 值。
你还可以使用索引访问操作符 []
向可变 map 添加项目:
fun main() {
val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
juiceMenu["coconut"] = 150 // Add key "coconut" with value 150 to the map
println(juiceMenu)
// {apple=100, kiwi=190, orange=100, coconut=150}
}
要从可变 map 中移除项目,请使用 .remove()
函数:
fun main() {
val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
juiceMenu.remove("orange") // Remove key "orange" from the map
println(juiceMenu)
// {apple=100, kiwi=190}
}
要获取 map 中的项目数量,请使用 .count()
函数:
fun main() {
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println("This map has ${readOnlyJuiceMenu.count()} key-value pairs")
// This map has 3 key-value pairs
}
要检测 map 中是否已包含特定键,请使用 .containsKey()
函数:
fun main() {
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(readOnlyJuiceMenu.containsKey("kiwi"))
// true
}
要获取 map 的键或值的集合,请分别使用 keys
和 values
属性:
fun main() {
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(readOnlyJuiceMenu.keys)
// [apple, kiwi, orange]
println(readOnlyJuiceMenu.values)
// [100, 190, 100]
}
keys
和values
是对象属性的示例。要访问对象的属性,请在对象名称后加上句点.
,然后是属性名。属性在类章节中有更详细的讨论。 在本教程的此时,你只需了解如何访问它们。
要检测键或值是否在 map 中,请使用 in
操作符:
fun main() {
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println("orange" in readOnlyJuiceMenu.keys)
// true
// Alternatively, you don't need to use the keys property
println("orange" in readOnlyJuiceMenu)
// true
println(200 in readOnlyJuiceMenu.values)
// false
}
有关集合能做什么的更多信息,请参见集合。
现在你已经了解了基本类型以及如何管理集合,是时候探索你可以在程序中使用的控制流了。
练习
练习 1
你有一个“绿色”数字列表和一个“红色”数字列表。完成代码以打印总共有多少个数字。
fun main() {
val greenNumbers = listOf(1, 4, 23)
val redNumbers = listOf(17, 2)
// Write your code here
}
示例解答
fun main() {
val greenNumbers = listOf(1, 4, 23)
val redNumbers = listOf(17, 2)
val totalCount = greenNumbers.count() + redNumbers.count()
println(totalCount)
}
练习 2
你有一组服务器支持的协议。用户请求使用特定协议。完成程序以检测请求的协议是否受支持 (isSupported
必须是布尔值)。
fun main() {
val SUPPORTED = setOf("HTTP", "HTTPS", "FTP")
val requested = "smtp"
val isSupported = // Write your code here
println("Support for $requested: $isSupported")
}
示例解答
fun main() {
val SUPPORTED = setOf("HTTP", "HTTPS", "FTP")
val requested = "smtp"
val isSupported = requested.uppercase() in SUPPORTED
println("Support for $requested: $isSupported")
}
练习 3
定义一个 map,将整数 1 到 3 映射到其对应的拼写。使用此 map 拼写给定数字。
fun main() {
val number2word = // Write your code here
val n = 2
println("$n is spelt as '${<Write your code here >}'")
}
示例解答
fun main() {
val number2word = mapOf(1 to "one", 2 to "two", 3 to "three")
val n = 2
println("$n is spelt as '${number2word[n]}'")
}