Kotlin 列表
最后修改于 2024 年 1 月 29 日
本文介绍了如何在 Kotlin 中使用列表。 列表是元素的通用有序集合。
Kotlin 区分只读列表和可变列表。 只读列表使用 listOf
创建,可变列表使用 mutableListOf
创建。
Kotlin listOf
listOf
方法在 Kotlin 中创建一个新的只读列表。
package com.zetcode fun main() { val words = listOf("pen", "cup", "dog", "spectacles") println("The list contains ${words.size} elements.") }
此示例使用 listOf
创建一个包含单词的新列表。 列表的大小由 size
属性确定。
Kotlin 列表基础
在下一个示例中,我们有一个简单的 Kotlin 列表示例。
package com.zetcode fun main() { val nums = listOf(11, 5, 3, 8, 1, 9, 6, 2) val len = nums.count() val max = nums.max() val min = nums.min() val sum = nums.sum() val avg = nums.average() val msg = """ max: $max, min: $min, count: $len, sum: $sum, average: $avg """ println(msg.trimIndent()) }
此示例创建一个数字列表并计算一些统计数据。
val nums = listOf(11, 5, 3, 8, 1, 9, 6, 2)
Kotlin 只读列表使用 listOf
函数创建。
val len = nums.count() val max = nums.max() val min = nums.min() val sum = nums.sum() val avg = nums.average()
我们计算值的数量、最大值、最小值、总和以及值的平均值。
max: 11, min: 1, count: 8, sum: 45, average: 5.625
Kotlin 列表索引
列表的每个元素都有一个索引。 Kotlin 列表索引从零开始。 最后一个元素的索引为 len-1
。
package com.zetcode fun main() { val words = listOf("pen", "cup", "dog", "person", "cement", "coal", "spectacles", "cup", "bread") val w1 = words.get(0) println(w1) val w2 = words[0] println(w2) val i1 = words.indexOf("cup") println("The first index of cup is $i1") val i2 = words.lastIndexOf("cup") println("The last index of cup is $i2") val i3 = words.lastIndex println("The last index of the list is $i3") }
此示例演示了 Kotlin 列表索引操作。
val w1 = words.get(0)
使用 get
方法检索一个元素。 该方法将要检索的元素的索引作为参数。
val w2 = words[0]
我们也可以使用经典的 C 索引操作。
val i1 = words.indexOf("cup")
indexOf
返回列表中单词第一次出现的索引。
val i2 = words.lastIndexOf("cup")
lastIndexOf
返回列表中单词最后一次出现的索引。
val i3 = words.lastIndex
lastIndex
属性返回列表中最后一个项目的索引,如果列表为空,则返回 -1
pen pen The first index of cup is 1 The last index of cup is 7 The last index of the list is 8
Kotlin 使用随机整数初始化
在下一个示例中,我们使用随机整数值初始化一个列表。
package com.zetcode import kotlin.random.Random fun main() { val nums = List(10) { Random.nextInt(0, 100) } println(nums) }
我们使用 Random.nextInt
初始化一个包含 0 到 100 之间十个整数的列表。
Kotlin 列表计数
count
方法返回列表中元素的数量。
package com.zetcode fun main() { val nums = listOf(4, 5, 3, 2, 1, -1, 7, 6, -8, 9, -12) val len = nums.count() println("There are $len elements") val size = nums.size println("The size of the list is $size") val n1 = nums.count { e -> e < 0 } println("There are $n1 negative values") val n2 = nums.count { e -> e % 2 == 0 } println("There are $n2 even values") }
此示例返回列表中值的数量、负值的数量和偶数值的数量。
val len = nums.count() println("There are $len elements") val size = nums.size println("The size of the list is $size")
我们可以使用 count
方法或 size
属性来确定列表中元素的数量。
val n1 = nums.count { e -> e < 0 }
count
可以将谓词函数作为参数。 在我们的例子中,它对小于 0 的值返回 true。
val n2 = nums.count { e -> e % 2 == 0 }
我们获得列表中偶数值的数量。
There are 11 elements The size of the list is 11 There are 3 negative values There are 5 even values
Kotlin 列表的第一个和最后一个元素
我们有获取列表的第一个和最后一个元素的方法。
package com.zetcode fun main() { val words = listOf("pen", "cup", "dog", "person", "cement", "coal", "spectacles") val w1 = words.first() println(w1) val w2 = words.last() println(w2) val w3 = words.findLast { w -> w.startsWith('c') } println(w3) val w4 = words.first { w -> w.startsWith('c') } println(w4) }
此示例创建一个单词列表。 我们获取列表的第一个和最后一个元素。
val w1 = words.first()
我们使用 first
获取第一个元素。
val w2 = words.last()
我们使用 last
获取最后一个元素。
val w3 = words.findLast { w -> w.startsWith('c') }
我们使用 findLast
检索以“c”开头的列表的最后一个元素。
val w4 = words.first { w -> w.startsWith('c') }
我们使用 first
检索以“c”开头的列表的第一个元素。
pen spectacles coal cup
Kotlin 列表迭代
列表迭代或列表循环是逐个遍历列表元素的过程。
package com.zetcode fun main() { val words = listOf("pen", "cup", "dog", "person", "cement", "coal", "spectacles") words.forEach { e -> print("$e ") } println() for (word in words) { print("$word ") } println() for (i in 0 until words.size) { print("${words[i]} ") } println() words.forEachIndexed({i, e -> println("words[$i] = $e")}) val it: ListIterator<String> = words.listIterator() while (it.hasNext()) { val e = it.next() print("$e ") } println() }
此示例显示了在 Kotlin 中循环遍历列表的五种方法。
words.forEach { e -> print("$e ") }
forEach
对每个列表元素执行给定的操作。 我们向其传递一个匿名函数,该函数打印当前元素。
for (word in words) { print("$word ") }
我们使用 for
循环列表。 for
循环逐个遍历列表元素;在每个循环中,word
变量指向列表中的下一个元素。
for (i in 0 until words.size) { print("${words[i]} ") }
另一种 for
循环利用列表的大小。 until
关键字创建列表索引的范围。
words.forEachIndexed({i, e -> println("words[$i] = $e")})
使用 forEachIndexed
方法,我们循环遍历列表,在每次迭代中都可以使用索引和值。
val it: ListIterator<String> = words.listIterator() while (it.hasNext()) { val e = it.next() print("$e ") }
最后一种方法是使用 ListIterator
和 while
循环。
pen cup dog person cement coal spectacles pen cup dog person cement coal spectacles pen cup dog person cement coal spectacles words[0] = pen words[1] = cup words[2] = dog words[3] = person words[4] = cement words[5] = coal words[6] = spectacles pen cup dog person cement coal spectacles
Kotlin 列表排序
以下示例演示了如何在 Kotlin 中对 List 值进行排序。 由于使用 listOf
创建的列表是只读的,因此这些方法不会更改列表,而是返回一个新的已修改列表。
package com.zetcode data class Car(val name: String, val price: Int) fun main() { val nums = listOf(11, 5, 3, 8, 1, 9, 6, 2) val sortAsc = nums.sorted() println(sortAsc) val sortDesc = nums.sortedDescending() println(sortDesc) val revNums = nums.reversed() println(revNums) val cars = listOf(Car("Mazda", 6300), Car("Toyota", 12400), Car("Skoda", 5670), Car("Mercedes", 18600)) val res = cars.sortedBy { car -> car.name } res.forEach { e -> println(e) } println("*************") val res2 = cars.sortedByDescending { car -> car.name } res2.forEach { e -> println(e) } }
此示例按升序和降序对列表值进行排序,反转列表元素,并按名称对汽车对象进行排序。
val sortAsc = nums.sorted()
sorted
方法返回一个列表,其中所有元素都根据其自然排序顺序排序。
val sortDesc = nums.sortedDescending()
sortedDescending
方法返回一个列表,其中所有元素都按降序排列,按其自然排序顺序排列。
val revNums = nums.reversed()
reversed
方法返回一个列表,其中元素的顺序颠倒。
val cars = listOf(Car("Mazda", 6300), Car("Toyota", 12400), Car("Skoda", 5670), Car("Mercedes", 18600))
我们创建一个汽车对象列表。 可以按其名称或价格对这些对象进行排序。
val res = cars.sortedBy { car -> car.name }
使用 sortedBy
,我们按名称按升序对汽车进行排序。
val res2 = cars.sortedByDescending { car -> car.name }
使用 sortedByDescending
,我们按名称按降序对汽车进行排序。
[1, 2, 3, 5, 6, 8, 9, 11] [11, 9, 8, 6, 5, 3, 2, 1] [2, 6, 9, 1, 8, 3, 5, 11] Car(name=Mazda, price=6300) Car(name=Mercedes, price=18600) Car(name=Skoda, price=5670) Car(name=Toyota, price=12400) ************* Car(name=Toyota, price=12400) Car(name=Skoda, price=5670) Car(name=Mercedes, price=18600) Car(name=Mazda, price=6300)
Kotlin 列表包含
使用 contains
方法,我们可以检查列表是否包含指定的元素。
package com.zetcode fun main() { val nums = listOf(4, 5, 3, 2, 1, -1, 7, 6, -8, 9, -12) val r = nums.contains(4) if (r) println("The list contains 4") else println("The list does not contain 4") val r2 = nums.containsAll(listOf(1, -1)) if (r2) println("The list contains -1 and 1") else println("The list does not contain -1 and 1") }
可以检查列表是否包含一个或多个元素。
val r = nums.contains(4)
这里我们检查 nums
列表是否包含 4。该方法返回一个布尔值。
val r2 = nums.containsAll(listOf(1, -1))
此行检查列表是否包含两个值:1 和 -1。
The list contains 4 The list contains -1 and 1
Kotlin 可变列表
使用 mutableListOf
,我们可以在 Kotlin 中创建可变列表。 我们可以在可变列表中添加新元素、删除元素和修改元素。
package com.zetcode fun main() { val nums = mutableListOf(3, 4, 5) nums.add(6) nums.add(7) nums.addAll(listOf(8, 9, 10)) nums.add(0, 0) nums.add(1, 1) nums.add(2, 2) println(nums) nums.shuffle() println(nums) nums.sort() println(nums) nums.removeAt(0) nums.remove(10) println(nums) nums.replaceAll { e -> e * 2 } println(nums) nums.retainAll(listOf(12, 14, 16, 18)) println(nums) nums.fill(0) println(nums) nums.set(0, 22) println(nums[0]) nums.clear() if (nums.isEmpty()) println("The list is empty") else println("The list is not epty") }
此示例创建一个可变列表,并介绍了它的几种方法。
val nums = mutableListOf(3, 4, 5)
我们创建一个包含三个整数元素的可变列表。
nums.add(6) nums.add(7) nums.addAll(listOf(8, 9, 10))
add
在列表的末尾添加一个新元素。 addAll
在列表的末尾添加多个元素。
nums.shuffle()
shuffle
方法随机重新排列列表元素。 混洗就地进行;即原始列表被修改。
nums.sort()
这些元素按其自然升序排序。
nums.removeAt(0) nums.remove(10)
removeAt
方法删除指定索引处的元素。 remove
方法从列表中删除指定元素第一次出现的位置。
nums.replaceAll { e -> e * 2 }
replaceAll
方法使用给定的函数修改列表的所有元素。 在我们的例子中,我们创建一个匿名函数,该函数将每个元素乘以 2。
nums.retainAll(listOf(12, 14, 16, 18))
retainAll
方法仅保留参数中指定的元素;其他元素将被删除。
nums.fill(0)
fill
方法将所有元素替换为给定的值。
nums.set(0, 22)
set
方法将列表中指定位置的元素替换为给定的元素。
nums.clear()
clear
方法从列表中删除所有元素。
if (nums.isEmpty()) println("The list is empty") else println("The list is not epty")
使用 isEmpty
方法,我们检查列表是否为空。
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [2, 3, 6, 1, 8, 0, 7, 5, 10, 9, 4] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [1, 2, 3, 4, 5, 6, 7, 8, 9] [2, 4, 6, 8, 10, 12, 14, 16, 18] [12, 14, 16, 18] [0, 0, 0, 0] 22 The list is empty
Kotlin 列表切片
切片是列表的一部分。 可以使用 slice
方法创建切片。 该方法获取要选择的元素的索引。
package com.zetcode fun main() { val nums = listOf(1, 2, 3, 4, 5, 6) val nums2 = nums.slice(1..3) println(nums2) val nums3 = nums.slice(listOf(3, 4, 5)) println(nums3) }
在此示例中,我们创建一个整数列表。 从列表中,我们生成两个切片。
val nums2 = nums.slice(1..3)
我们使用范围运算符创建一个列表切片,其中包含索引为 1、2 和 3 的元素。所有索引都是包含的。
val nums3 = nums.slice(listOf(3, 4, 5))
在第二个示例中,我们显式提供索引列表。
[2, 3, 4] [4, 5, 6]
Kotlin 列表最大值
以下示例处理查找列表的最大值。
package com.zetcode data class Car(val name: String, val price: Int) fun main() { val nums = listOf(11, 5, 23, 8, 1, 9, 6, 2) println(nums.max()) val cars = listOf(Car("Mazda", 6300), Car("Toyota", 12400), Car("Skoda", 5670), Car("Mercedes", 18600)) val car = cars.maxBy { car -> car.price } println("The max price is ${car.price} of ${car.name}") }
此示例找到一个整数列表和一个汽车对象的最大值。
val nums = listOf(11, 5, 23, 8, 1, 9, 6, 2) println(nums.max())
整数列表的最大值很容易用 max
找到。
val cars = listOf(Car("Mazda", 6300), Car("Toyota", 12400), Car("Skoda", 5670), Car("Mercedes", 18600)) val car = cars.maxBy { car -> car.price } println("The max price is ${car.price} of ${car.name}")
当我们处理对象时,我们需要指定用于查找最大值的属性。 maxBy
方法给出了一个选择器函数,该函数选择汽车的 price
属性。
23 The max price is 18600 of Mercedes
Kotlin 列表过滤
过滤是一种操作,其中只有满足特定条件的元素才能通过。
package com.zetcode data class Car(val name: String, val price: Int) fun main() { val words = listOf("pen", "cup", "dog", "person", "cement", "coal", "spectacles") val words2 = words.filter { e -> e.length == 3 } words2.forEach { e -> print("$e ") } println() val words3 = words.filterNot { e -> e.length == 3 } words3.forEach { e -> print("$e ") } println() val cars = listOf(Car("Mazda", 6300), Car("Toyota", 12400), Car("Skoda", 5670), Car("Mercedes", 18600)) val res = cars.filter { car -> car.price > 10000 } res.forEach { e -> println(e) } }
此示例介绍了 Kotlin 列表上的过滤操作。
val words2 = words.filter { e -> e.length == 3 }
filter
方法将谓词函数作为参数。 谓词给出一个元素必须满足的条件。 我们过滤掉长度等于 3 的单词。
val words3 = words.filterNot { e -> e.length == 3 }
filterNot
执行相反的操作:它允许通过不满足给定条件的元素。
val cars = listOf(Car("Mazda", 6300), Car("Toyota", 12400), Car("Skoda", 5670), Car("Mercedes", 18600)) val res = cars.filter { car -> car.price > 10000 }
这些行过滤掉价格大于 10000 的汽车对象。
pen cup dog person cement coal spectacles Car(name=Toyota, price=12400) Car(name=Mercedes, price=18600)
Kotlin 列表映射
映射操作通过对列表的每个元素应用转换函数来返回一个已修改的列表。
package com.zetcode fun main() { val nums = listOf(1, 2, 3, 4, 5, 6) val nums2 = nums.map { e -> e * 2 } println(nums2) }
我们有一个整数列表。 使用 map
方法,我们将每个列表元素乘以 2。
[2, 4, 6, 8, 10, 12]
Kotlin 列表归约
归约 是一种终端操作,它将列表值聚合为单个值。 reduce
方法对累加器和每个元素(从左到右)应用一个函数,以将其归约为单个值。
package com.zetcode fun main() { val nums = listOf(4, 5, 3, 2, 1, 7, 6, 8, 9) val sum = nums.reduce { total, next -> total + next } println(sum) val colours = listOf("red", "green", "white", "blue", "black") val res = colours.reduceRight { next, total -> "$total-$next" } println(res) }
在此示例中,我们对一个整数和字符串列表使用 reduce 操作。
val sum = nums.reduce { total, next -> total + next }
我们计算值的总和。total
是累加器,next
是列表中的下一个值。
val res = colours.reduceRight { next, total -> "$total-$next" }
reduceRight
从最后一个元素开始累加值,并将操作从右到左应用于每个元素和当前累加器值。
45 black-blue-white-green-red
Kotlin 列表折叠
折叠操作类似于归约。 折叠 是一种终端操作,它将列表值聚合为单个值。 区别在于折叠从初始值开始。
package com.zetcode fun main() { val expenses = listOf(20, 40, 80, 15, 25) val cash = 550 val res = expenses.fold(cash) {total, next -> total - next} println(res) }
我们有一个费用清单。 这些费用适用于可用的现金初始金额。
val res = expenses.fold(cash) {total, next -> total - next}
使用 fold
,我们从 cash
中扣除所有费用并返回剩余值。
370
这是我们减去所有费用后的金额。
Kotlin 列表块
有时我们在进行归约时需要使用更多列表元素。 我们可以使用 chunked
方法将列表拆分为列表列表。
package com.zetcode fun main() { val nums = listOf(1, 2, 3, 4, 5, 6) val res = nums.chunked(2).fold(0) { total, next -> total + next[0] * next[1] } println(res) }
在此示例中,我们有一个包含六个值的列表。 我们希望实现以下操作:1*2 + 3*4 + 5*6
。 为此,我们需要将列表拆分为两个值的块。
val res = nums.chunked(2).fold(0) { total, next -> total + next[0] * next[1] }
我们将列表拆分为一个包含两个元素的列表列表,并对其应用折叠。 next
是一个列表,我们可以在其上使用索引操作。
44
Kotlin 列表分区
分区操作将原始集合拆分为成对的列表。 第一个列表包含谓词返回 true 的元素,而第二个列表包含谓词返回 false 的元素。
package com.zetcode fun main(args: Array<String>) { val nums = listOf(4, -5, 3, 2, -1, 7, -6, 8, 9) val (nums2, nums3) = nums.partition { e -> e < 0 } println(nums2) println(nums3) }
我们有一个整数列表。 使用 partition
方法,我们将列表拆分为两个子列表;一个包含负值,另一个包含正值。
val (nums2, nums3) = nums.partition { e -> e < 0 }
使用解构声明,我们同时将列表拆分为两部分。
[-5, -1, -6] [4, 3, 2, 7, 8, 9]
Kotlin 列表分组
groupBy
方法按给定选择器函数(应用于每个元素)返回的键对原始列表的元素进行分组。 它返回一个 Map,其中每个组键都与一个对应的元素列表相关联。
package com.zetcode fun main() { val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8) val res = nums.groupBy { if (it % 2 == 0) "even" else "odd" } println(res) val words = listOf("as", "pen", "cup", "doll", "my", "dog", "spectacles") val res2 = words.groupBy { it.length } println(res2) }
此示例展示了如何使用 groupBy
方法。
val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8) val res = nums.groupBy { if (it % 2 == 0) "even" else "odd" } println(res)
这些行创建一个 Map,其中包含两个键:“even”和“odd”。 “even”指向一个偶数值列表,而“odd”指向一个奇数值列表。
val words = listOf("as", "pen", "cup", "doll", "my", "dog", "spectacles") val res2 = words.groupBy { it.length }
在这里,我们创建了一个包含整数键的 Map。 每个键对具有一定长度的单词进行分组。
{odd=[1, 3, 5, 7], even=[2, 4, 6, 8]} {2=[as, my], 3=[pen, cup, dog], 4=[doll], 10=[spectacles]}
Kotlin 列表 any
如果至少有一个元素与给定的谓词函数匹配,则 any
方法返回 true。
package com.zetcode fun main() { val nums = listOf(4, 5, 3, 2, -1, 7, 6, 8, 9) val r = nums.any { e -> e > 10 } if (r) println("There is a value greater than ten") else println("There is no value greater than ten") val r2 = nums.any { e -> e < 0 } if (r2) println("There is a negative value") else println("There is no negative value") }
该示例显示了 any
的用法。
val r2 = nums.any { e -> e < 0 }
在这里,我们检查列表是否包含至少一个负值。 该方法返回一个布尔值。
Kotlin 列表 all
如果所有元素都满足给定的谓词函数,则 all
返回 true。
package com.zetcode fun main() { val nums = listOf(4, 5, 3, 2, -1, 7, 6, 8, 9) val nums2 = listOf(-3, -4, -2, -5, -7, -8) // testing for positive only values val r = nums.all { e -> e > 0 } if (r) println("nums list contains only positive values") else println("nums list does not contain only positive values") // testing for negative only values val r2 = nums2.all { e -> e < 0 } if (r2) println("nums2 list contains only negative values") else println("nums2 list does not contain only negative values") }
此示例显示了 all
的用法。
// testing for positive only values val r = nums.all { e -> e > 0 }
在这里,我们测试 nums
列表是否仅包含正值。
Kotlin 列表删除
使用删除操作,我们从列表中排除一些元素。
package com.zetcode fun main() { val nums = listOf(4, 5, 3, 2, 1, -1, 7, 6, -8, 9, -12) val nums2 = nums.drop(3) println(nums2) val nums3 = nums.dropLast(3) println(nums3) val nums4 = nums.sorted().dropWhile { e -> e < 0 } println(nums4) val nums5 = nums.sorted().dropLastWhile { e -> e > 0 } println(nums5) }
该示例显示了不同删除操作的用法。
val nums2 = nums.drop(3)
使用 drop
方法,我们排除前三个元素。
val nums3 = nums.dropLast(3)
使用 dropLast
方法,我们排除最后三个元素。
val nums4 = nums.sorted().dropWhile { e -> e < 0 }
使用 dropWhile
方法,我们排除满足给定谓词函数的前 n 个元素。
val nums5 = nums.sorted().dropLastWhile { e -> e > 0 }
使用 dropLastWhile
方法,我们排除满足给定谓词函数的最后 n 个元素。
[2, 1, -1, 7, 6, -8, 9, -12] [4, 5, 3, 2, 1, -1, 7, 6] [1, 2, 3, 4, 5, 6, 7, 9] [-12, -8, -1]
Kotlin 列表取值
取值操作是对删除操作的补充。 取值方法通过选取一些元素来形成一个新列表。
package com.zetcode fun main() { val nums = listOf(4, 5, 3, 2, 1, -1, 7, 6, -8, 9, -12) val nums2 = nums.take(3) println(nums2) val nums3 = nums.takeLast(3) println(nums3) val nums4 = nums.sorted().take(3) println(nums4) val nums5 = nums.takeWhile { e -> e > 0 } println(nums5) val nums6 = nums.sortedDescending().takeWhile { e -> e > 0 } println(nums6) val nums7 = nums.takeIf { e -> e.contains(6) } println(nums7) }
该示例显示了各种取值方法的用法。
val nums2 = nums.take(3)
take
方法创建一个新列表,该列表包含原始列表的前三个元素。
val nums3 = nums.takeLast(3)
takeLast
方法将最后几个元素放入新列表。
val nums5 = nums.takeWhile { e -> e > 0 }
takeWhile
选取满足谓词函数的前 n 个元素。
val nums7 = nums.takeIf { e -> e.contains(6) }
takeIf
方法选取列表的所有元素(如果满足谓词函数中的条件)。
[4, 5, 3] [-8, 9, -12] [-12, -8, -1] [4, 5, 3, 2, 1] [9, 7, 6, 5, 4, 3, 2, 1] [4, 5, 3, 2, 1, -1, 7, 6, -8, 9, -12]
来源
在本文中,我们介绍了 Kotlin 列表。
列出 所有 Kotlin 教程。