重学Kotlin(七)集合

集合概述

  • List 是一个有序集合,可通过索引(反映元素位置的整数)访问元素。 元素顺序很重要并且可以重复。
  • Set 是唯一元素的集合。元素无顺序不可重复。
  • Map(或者字典)是一组键值对。键是唯一的,值可以重复。

var 集合可以进行重新赋值和更改其中元素
val 集合不可以进行重新赋值,但可以更改其中元素

Mutable翻译中文为:可变;可变的;易变的;
需要写操作的那么就需要Mutable开头
所有就有了

listOf()
mutableListOf()

setOf()
mutableSetOf()

mapOf()
mutableMapOf()

创建空集合需指定类型

   listOf(1,2,3)
   listOf<Int>()
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3)

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

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

创建空集合时,应指定集合将包含的元素类型。

val empty1 = emptyList<String>()
val empty2 = emptySet<String>()
val empty3 = emptyMap<String,String>()

集合复制
如果在源集合中添加或删除元素,则不会影响副本。
副本也可以独立于源集合进行更改。

listOf<Int>().toList()
listOf<Int>().toMutableList()
listOf<Int>().toSet()
listOf<Int>().toMutableSet()

迭代器

Iterable 接口的继承者 (包括 Set 与 List)可以通过调用 iterator() 函数获得迭代器。
一旦获得迭代器它就指向集合的第一个元素;调用 next() 函数将返回此元素,并将迭代器指向下一个元素(如果下一个元素存在)。
三种迭代数据的方式
方式一

val numbers = listOf("one", "two", "three", "four")
    val numbersIterator = numbers.iterator()
    while (numbersIterator.hasNext()) {
        println(numbersIterator.next())
    }

方式二

val numbers = listOf("one", "two", "three", "four")
  for (item in numbers) {
        println(item)
    }
  for ((index,value) in numbers.withIndex()) {
            index
            value
        }
  for (item in numbers.withIndex()) {
            item.index
            item.value
        }
  for (index in numbers.indices) {
          numbers[index]
        }

方式三

 val numbers = listOf("one", "two", "three", "four")
    numbers.forEach {
        println(it)
    }

对于列表,有一个特殊的迭代器实现: ListIterator。 它支持列表双向迭代:正向与反向。

val numbers = listOf("one", "two", "three", "four")
    val listIterator = numbers.listIterator()
    while (listIterator.hasNext()) listIterator.next()
    println("Iterating backwards:")
    while (listIterator.hasPrevious()) {
        print("Index: ${listIterator.previousIndex()}")
        println(", value: ${listIterator.previous()}")
    }

可变迭代器

迭代可变集合并增删改
新增和修改:MutableListIterator
删除:MutableIterator

 val numbers = mutableListOf("one", "four", "four")
    val mutableListIterator = numbers.listIterator()

    mutableListIterator.next()
    mutableListIterator.add("two")
    mutableListIterator.next()
    mutableListIterator.set("three")
    println(numbers)
 val numbers = mutableListOf("one", "two", "three", "four") 
    val mutableIterator = numbers.iterator()

    mutableIterator.next()
    mutableIterator.remove()    
    println("After removal: $numbers")

区间 in,downTo,step,until

if (i in 1..4) {  // 等同于 1 <= i && i <= 4
    print(i)
}
结果:1234
//反向迭代
for (i in 4 downTo 1) {
print(i)
}
结果:4321

增加步长

for (i in 1..8 step 2) print(i)//取索引:1,1+2,3+2,5+2
println()
for (i in 8 downTo 1 step 2) print(i)//取索引:8,8-2,6-2,4-2
结果:
1357
8642

不包含结尾数据

for (i in 1 until 10) {       // i in [1, 10), 10被排除
    print(i)
}

序列

序列:特殊场景大数据量替代集合的方案
Kotlin 中的序列(sequence)

集合中的拓展函数

集合转换

map,mapIndexed

val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 })
println(numbers.mapIndexed { idx, value -> value * idx })
结果:
[3, 6, 9]
[0, 2, 6]

过滤掉 null 值可以使用

mapNotNull() , mapIndexedNotNull()

val numbers = setOf(1, 2, 3)
println(numbers.mapNotNull { if ( it == 2) null else it * 3 })
println(numbers.mapIndexedNotNull { idx, value -> if (idx == 0) null else value * idx })
结果:
[3, 9]
[2, 6]

如果集合是键值对,使用

mapKeys ,mapValues

mapKeys :括号里的条件应用于键
mapValues :括号里的条件应用于值

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
println(numbersMap.mapKeys { it.key.toUpperCase() })
println(numbersMap.mapValues { it.value + it.key.length })
结果:返回为键值对
{KEY1=1, KEY2=2, KEY3=3, KEY11=11}
{key1=5, key2=6, key3=7, key11=16}

两个集合和键值对 相互转换

zip ,unzip

val colors = listOf("red", "brown", "grey")
        val animals = listOf("fox", "bear", "wolf")
        val news = colors zip animals
        for (new in news){
            println("${new.first},${new.second}")
        }

val twoAnimals = listOf("fox", "bear")
println(colors.zip(twoAnimals))

结果:
red,fox
brown,bear
grey,wolf
[(red, fox), (brown, bear)]

另一种写法,color和animal 为两个集合的元素

val colors = listOf("red", "brown", "grey")
val animals = listOf("fox", "bear", "wolf")

println(colors.zip(animals) { color, animal -> "The ${animal.capitalize()} is $color"})
结果:
[The Fox is red, The Bear is brown, The Wolf is grey]
val numberPairs = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
println(numberPairs.unzip())
结果:
([one, two, three, four], [1, 2, 3, 4])

通过集合构建键值对

associateWith,associateBy,associateBy(),associate()

associateWith:集合中的值作为新集合的key
associateBy:集合中的值作为新集合的value
associateBy():集合中的值作为新集合的value,函数方式构建
associate():函数方式构建

val numbers = listOf("one", "two", "three", "four")
println(numbers.associateWith { it.length })
结果:
{one=3, two=3, three=5, four=4}

val numbers = listOf("one", "two", "three", "four")
println(numbers.associateBy { it.length })
结果:key不可重复所以是3个元素
{3=two, 5=three, 4=four}

带参数的写法

println(numbers.associateBy(keySelector = { it.length }, valueTransform = { it }))
结果:返回为键值对
{3=two, 5=three, 4=four}
val numbers = listOf("one", "two", "three", "four")
println(numbers.associate { n -> n to n.length })  
结果:返回为键值对
{one=3, two=3, three=5, four=4}

对嵌套的集合进行打平使用

flatten,flatMap

flatMap = 先调用map后调用flatten

val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
println(numberSets.flatten())
结果:
[1, 2, 3, 4, 5, 6, 1, 2]

集合转换为字符串

joinToString,joinTo

val numbers = listOf("one", "two", "three", "four")

println(numbers)         
println(numbers.joinToString())

val listString = StringBuffer("The list of numbers: ")
numbers.joinTo(listString)
println(listString)
结果:
[one, two, three, four]
one, two, three, four
The list of numbers: one, two, three, four

自定义字符串可以指定参数

val numbers = listOf("one", "two", "three", "four")    
println(numbers.joinToString(separator = " | ", prefix = "start: ", postfix = ": end"))
结果:返回为字符串
start: one | two | three | four: end

较大的集合,超出 limit的其他元素被 truncated 参数的单个值替换。

val numbers = (1..100).toList()
println(numbers.joinToString(limit = 10, truncated = "<...>"))
结果:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, <...>

修改元素的表现格式

val numbers = listOf("one", "two", "three", "four")
println(numbers.joinToString { "Element: ${it.toUpperCase()}"})
结果:返回为字符串
Element: ONE, Element: TWO, Element: THREE, Element: FOUR

集合过滤

filter,filterNot,filterNotNull,filterIndexed,filterIsInstance

filter,filterNot:只检查元素的值
filterNotNull:返回非空元素
filterIndexed:检查元素的索引和元素的值
filterIsInstance:返回指定类型的元素

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

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap)
结果:
[three, four]
{key11=11}
val numbers = listOf("one", "two", "three", "four")

val filteredIdx = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5)  }
val filteredNot = numbers.filterNot { it.length <= 3 }


println(filteredIdx)
println(filteredNot)

val numbers2 = listOf(null, "one", "two", null)
numbers2.filterNotNull().forEach {
    println("长度"+it.length)   // 对可空的 String 来说长度不可用
}
结果:
[two, four]
[three, four]
长度3
长度3
val numbers = listOf(null, 1, "two", 3.0, "four")
println("All String elements in upper case:")
numbers.filterIsInstance<String>().forEach {
    println(it.toUpperCase())
}
结果:提取了类型为String的数据
All String elements in upper case:
TWO
FOUR

过滤 map 的特定函数:按键或按值。 这两种方式,都有对应的函数: filterKeys() 和 filterValues() 。 两者都将返回一个新 Map

filterKeys,filterValues
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredKeysMap = numbersMap.filterKeys { it.endsWith("1") }
val filteredValuesMap = numbersMap.filterValues { it < 10 }

println(filteredKeysMap)
println(filteredValuesMap)
结果:
{key1=1, key11=11}
{key1=1, key2=2, key3=3}

1个集合分为2个集合,符合条件的和不符合条件的

划分partition

val numbers = listOf("one", "two", "three", "four")
val (match, rest) = numbers.partition { it.length > 3 }

println(match)
println(rest)
结果:
[three, four]
[one, two]

检验any,one,all

any:集合元素只要有一个包含返回true
none:集合元素都不包含返回true
all:集合元素都包含返回true
空集合永远返回true

val numbers = listOf("one", "two", "three", "four")

println(numbers.any { it.endsWith("e") })
println(numbers.none { it.endsWith("a") })
println(numbers.all { it.endsWith("e") })
//空集合调用这3个函数都返回true
println(emptyList<Int>().all { it > 5 })   // vacuous truth
结果:
true
true
false
true

any() 和 none() 不带参数只能检查集合是否为空

加减操作符

在 Kotlin 中,为集合定义了 plus (+) 和 minus (-) 操作符。 它们把一个集合作为第一个操作数;第二个操作数可以是一个元素或者是另一个集合。 返回值是一个新的只读集合:

val numbers = listOf("one", "two", "three", "four")

val plusList = numbers + "five"
val minusList = numbers - listOf("three", "four")
println(plusList)
println(minusList)
结果:返回为list
[one, two, three, four, five]
[one, two]

分组groupBy ,groupingBy

val numbers = listOf("one", "two", "three", "four", "five")

println(numbers.groupBy { it.first().toUpperCase() })
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.toUpperCase() }))
结果:返回为键值对
{O=[one], T=[two, three], F=[four, five]}
{o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}

取集合的一部分

slice,take,takeLast,drop,dropLast

slice:返回给定索引的集合元素列表
take:从头开始获取指定数量的元素
takeLast:从尾开始获取指定数量的元素
drop:从头去除给定数量的元素
dropLast:从尾去除给定数量的元素


val numbers = listOf("one", "two", "three", "four", "five", "six")    
println(numbers.slice(1..3))
println(numbers.slice(0..4 step 2))//0,0+2,2+2
println(numbers.slice(setOf(3, 5, 0)))  
结果:返回list
[two, three, four]
[one, three, five]
[four, six, one] 
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.take(3))
println(numbers.takeLast(3))
println(numbers.drop(1))
println(numbers.dropLast(5))
结果:返回list
[one, two, three]
[four, five, six]
[two, three, four, five, six]
[one]

takeWhile,takeLastWhile,dropWhile,dropLastWhile

takeWhile:从头循环获取指定条件元素,直到碰到首个不符合条件元素终止获取
takeLastWhile:从尾循环获取指定条件元素,直到碰到首个不符合条件元素终止获取
dropWhile:从头循环去除指定条件元素,直到碰到首个不符合条件元素终止去除
dropLastWhile:从尾循环去除指定条件元素,直到碰到首个不符合条件元素终止去除

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.takeWhile { !it.startsWith('f') })
println(numbers.takeLastWhile { it != "three" })
println(numbers.dropWhile { it.length == 3 })
println(numbers.dropLastWhile { it.contains('i') })
结果:返回符合条件的集合
[one, two, three]
[four, five, six]
[three, four, five, six]
[one, two, three, four]

Chunked

一个集合根据指定length分成多个子集合

val numbers = (0..13).toList()
println(numbers.chunked(3))
结果:返回嵌套集合
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]

对子集合进行累加

val numbers = (0..13).toList() 
println(numbers.chunked(3) { it.sum() })
结果:返回集合
[3, 12, 21, 30, 25]

Windowed,zipWithNext

一个集合根据指定length分成多个子集合,但每个索引都取

val numbers = listOf("one", "two", "three", "four", "five")    
println(numbers.windowed(3))
结果:
[[one, two, three], [two, three, four], [three, four, five]]

可选参数更灵活

val numbers = (1..10).toList()
//partialWindows = true 代表最后[9, 10]补足
println(numbers.windowed(3, step = 2, partialWindows = true))
println(numbers.windowed(3) { it.sum() })
结果:
[[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]]
[6, 9, 12, 15, 18, 21, 24, 27]
    val numbers = listOf("one", "two", "three", "four", "five")    
    println(numbers.zipWithNext())
    println(numbers.zipWithNext() { s1, s2 -> s1.length > s2.length})
    结果:返回键值对,返回集合
    [(one, two), (two, three), (three, four), (four, five)]
   [false, false, true, false]

取单个元素

elementAt,elementAtOrNull,elementAtOrElse,first,last,firstOrNull,lastOrNull,find,findLast,random

elementAt:下标越界会抛异常,对于不提供索引访问或非静态已知提供索引访问的集合很有用。 在使用 List 的情况下,使用索引访问操作符 (get() 或 [])更为习惯。
elementAtOrNull:下标越界返回null,不会抛异常
elementAtOrElse:下标越界返回指定错误
first:获取第一个元素,下标越界会抛异常
last:获取最后一个元素,下标越界会抛异常
firstOrNull:下标越界返回null,不会抛异常
lastOrNull:下标越界返回null,不会抛异常
find:代替 firstOrNull()
findLast:代替 lastOrNull()
random:随机

val numbers = linkedSetOf("one", "two", "three", "four", "five")
println(numbers.elementAt(3))    

val numbersSortedSet = sortedSetOf("one", "two", "three", "four")
println(numbersSortedSet.elementAt(0)) // 元素以升序存储
结果:
four
four
val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.elementAtOrNull(5))
println(numbers.elementAtOrElse(5) { index -> "The value for index $index is undefined"})
结果:
null
The value for index 5 is undefined
val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.first())    
println(numbers.last())  
结果:
one
five
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.first { it.length > 3 })
println(numbers.last { it.startsWith("f") })
结果:
three
five
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.firstOrNull { it.length > 6 })
结果:
null
val numbers = listOf(1, 2, 3, 4)
println(numbers.find { it % 2 == 0 })
println(numbers.findLast { it % 2 == 0 })
结果:
2
4
val numbers = listOf(1, 2, 3, 4)
println(numbers.random())
结果:
随机

contains,in ,isEmpty,isNotEmpty

你可以使用 in 关键字以操作符的形式调用 contains()

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.contains("four"))
println("zero" in numbers)

println(numbers.containsAll(listOf("four", "two")))
println(numbers.containsAll(listOf("one", "zero")))
结果:
true
false
true
false

isEmpty() 和 isNotEmpty() 来检查集合中是否包含任何元素。

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.isEmpty())
println(numbers.isNotEmpty())

val empty = emptyList<String>()
println(empty.isEmpty())
println(empty.isNotEmpty())
结果:
false
true
true
false

排序

sortedWith,compareBy

sortedWith:接收一个自定义的Comparator
compareBy:根据条件生成自定义Comparator

如需为类型定义自定义顺序,可以为其创建一个 Comparator。 Comparator 包含 compare() 函数:它接受一个类的两个实例并返回它们之间比较的整数结果

class Version(val major: Int, val minor: Int): Comparable<Version> {
    override fun compareTo(other: Version): Int {
        if (this.major != other.major) {
            return this.major - other.major
        } else if (this.minor != other.minor) {
            return this.minor - other.minor
        } else return 0
    }
}

fun main() {    
    println(Version(1, 2) > Version(1, 3))
    println(Version(2, 0) > Version(1, 5))
}
结果:
false
true

根据长度排序

val lengthComparator = Comparator { str1: String, str2: String -> str1.length - str2.length }
println(listOf("aaa", "bb", "c").sortedWith(lengthComparator))
结果:
[c, bb, aaa]

使用compareBy 根据条件排序

println(listOf("aaa", "bb", "c").sortedWith(compareBy { it.length }))
结果:
[c, bb, aaa]
自然顺序sorted,sortedDescending
val numbers = listOf("ane", "cwo", "bhree", "dour")

println("Sorted ascending: ${numbers.sorted()}")
println("Sorted descending: ${numbers.sortedDescending()}")
结果:默认按照首字母顺序进行了排序
Sorted ascending: [ane, bhree, cwo, dour]
Sorted descending: [dour, cwo, bhree, ane]
自定义顺序sortedBy,sortedByDescending
val numbers = listOf("one", "two", "three", "four")

val sortedNumbers = numbers.sortedBy { it.length }
println("$sortedNumbers")
val sortedByLast = numbers.sortedByDescending { it.length }
println("$sortedByLast")
结果:
[one, two, four, three]
[three, four, one, two]

使用sortedWith 接收自定义Comparator

println(listOf("aaa", "bb", "c").sortedWith(compareBy { it.length }))
结果:
[c, bb, aaa]
倒序reversed,asReversed

reversed:原始列表发送变化,倒序集合不会变化
asReversed:原始列表发生变化,倒序集合也会变化

如果原始列表不会发生变化,asReversed会比 reversed 更轻量,更合适。

val numbers = mutableListOf("one", "two", "three", "four")
val reversedNumbers = numbers.reversed()
println(reversedNumbers)
numbers.add("five")
println(reversedNumbers)
结果:
[four, three, two, one]
[four, three, two, one]
val numbers = mutableListOf("one", "two", "three", "four")
val reversedNumbers = numbers.asReversed()
println(reversedNumbers)
numbers.add("five")
println(reversedNumbers)
结果:
[four, three, two, one]
[five, four, three, two, one]

随机排序

val numbers = listOf("one", "two", "three", "four")
println(numbers.shuffled())
结果:
随机顺序

集合聚合操作

min,max,average,sum,count

min() 与 max() 分别返回最小和最大的元素;
average() 返回数字集合中元素的平均值;
sum() 返回数字集合中元素的总和;
count() 返回集合中元素的数量;

val numbers = listOf(6, 42, 10, 4)

println("Count: ${numbers.count()}")
println("Max: ${numbers.max()}")
println("Min: ${numbers.min()}")
println("Average: ${numbers.average()}")
println("Sum: ${numbers.sum()}")
结果:
Count: 4
Max: 42
Min: 4
Average: 15.5
Sum: 62

还有一些通过某些选择器函数或自定义 Comparator 来检索最小和最大元素的函数。

maxBy,minBy,maxWith,minWith

maxBy()/minBy() 接受一个选择器函数并返回使选择器返回最大或最小值的元素。
maxWith()/minWith() 接受一个 Comparator 对象并且根据此 Comparator 对象返回最大或最小元素

val numbers = listOf(5, 12, 10, 4)
val min3Remainder = numbers.minBy { it % 3 }
println(min3Remainder)

val strings = listOf("one", "two", "three", "four")
val longestString = strings.maxWith(compareBy { it.length })
println(longestString)
结果:
12
three

此外,有一些高级的求和函数,它们接受一个函数并返回对所有元素调用此函数的返回值的总和:

sumBy,sumByDouble

sumBy() 使用对集合元素调用返回 Int 值的函数。
sumByDouble() 与返回 Double 的函数一起使用

val numbers = listOf(5, 12, 10, 4)
println(numbers.sumBy { it * 2 })
println(numbers.sumByDouble { it.toDouble() / 2 })
结果:
62
15.5

Fold 与 reduce的累加

Fold ,reduce

它们依次将所提供的操作应用于集合元素并返回累积的结果。
操作有两个参数:先前的累积值和集合元素。

fold() 接受一个初始值并将其用作第一步的累积值
reduce() 则将第一个和第二个元素作为第一步的操作参数

val numbers = listOf(5, 2, 10, 4)

val sum = numbers.reduce { sum, element -> sum + element }
println(sum)
val sumDoubled = numbers.fold(1) { sum, element -> sum + element * 2 }
println(sumDoubled)
结果:
21
43

上面的实例展示了区别:fold() 用于计算加倍的元素之和。 如果将相同的函数传给 reduce(),那么它会返回另一个结果,因为在第一步中它将列表的第一个和第二个元素作为参数,所以第一个元素不会被加倍

reduceRight,foldRight

如需将函数以相反的顺序应用于元素,可以使用函数 reduceRight() 和 foldRight() 它们的工作方式类似于 fold() 和 reduce(),但从最后一个元素开始,然后再继续到前一个元素。 记住,在使用 foldRight 或 reduceRight 时,操作参数会更改其顺序:第一个参数变为元素,然后第二个参数变为累积值。

val numbers = listOf(5, 2, 10, 4)
val sumDoubledRight = numbers.foldRight(0) { element, sum -> sum + element * 2 }
println(sumDoubledRight)
结果:
42
reduceIndexed,foldIndexed,reduceRightIndexed,foldRightIndexed

你还可以使用将元素索引作为参数的操作。 为此,使用函数 reduceIndexed() 和 foldIndexed() 传递元素索引作为操作的第一个参数。

最后,还有将这些操作从右到左应用于集合元素的函数——reduceRightIndexed() 与 foldRightIndexed()

val numbers = listOf(5, 2, 10, 4)
val sumEven = numbers.foldIndexed(0) { idx, sum, element -> if (idx % 2 == 0) sum + element else sum }
println(sumEven)

val sumEvenRight = numbers.foldRightIndexed(0) { idx, element, sum -> if (idx % 2 == 0) sum + element else sum }
println(sumEvenRight)
结果:
15
15

所有reduce操作都会在空集合上引发异常。要接收null,请使用其*OrNull
reduceOrNull()
reduceRightOrNull()
reduceIndexedOrNull()
reduceRightIndexedOrNull()

集合写操作

添加元素

addAll() 将参数对象的每个元素添加到列表或集合中。参数可以是 Iterable、Sequence 或 Array。 接收者的类型和参数可能不同,例如,你可以将所有内容从 Set 添加到 List。

val numbers = mutableListOf(1, 2, 5, 6)
numbers.addAll(arrayOf(7, 8))
println(numbers)
numbers.addAll(2, setOf(3, 4))
println(numbers)
+=

+= 将元素或者集合追加到集合的末尾。

val numbers = mutableListOf("one", "two")
numbers += "three"
println(numbers)
numbers += listOf("four", "five")    
println(numbers)
结果:
[one, two, three]
[one, two, three, four, five]

删除元素

remove,removeAll,retainAll,clear,removeAt

删除单个元素

val numbers = mutableListOf(1, 2, 3, 4, 3)
numbers.remove(3)                    // 删除了第一个 `3`
println(numbers)
numbers.remove(5)                    // 什么都没删除
println(numbers)
结果:
[1, 2, 4, 3]
[1, 2, 4, 3]

删除多个元素
removeAll() 移除参数集合中存在的所有元素。 或者,你可以用谓词作为参数来调用它;在这种情况下,函数移除谓词产生 true 的所有元素。
retainAll() 与 removeAll() 相反:它移除除参数集合中的元素之外的所有元素。 当与谓词一起使用时,它只留下与之匹配的元素。
clear() 从列表中移除所有元素并将其置空。

val numbers = mutableListOf(1, 2, 3, 4)
println(numbers)
numbers.retainAll { it >= 3 }
println(numbers)
numbers.clear()
println(numbers)

val numbersSet = mutableSetOf("one", "two", "three", "four")
numbersSet.removeAll(setOf("one", "two"))
println(numbersSet)
结果:
[1, 2, 3, 4]
[3, 4]
[]
[three, four]

要从列表中删除指定位置的元素,请使用 removeAt() 函数

val numbers = mutableListOf(1, 2, 3, 4, 3)    
numbers.removeAt(1)
println(numbers)
结果:
[1, 3, 4, 3]
removeFirst() , removeLast() ,removeFirstOrNull() , removeLastOrNull()
val numbers = mutableListOf(1, 2, 3, 4, 3)    
numbers.removeFirst()
numbers.removeLast()
println(numbers)

val empty = mutableListOf<Int>()
// empty.removeFirst() // NoSuchElementException: List is empty.
empty.removeFirstOrNull() //null
结果:
[2, 3, 4]
-=

右边是单个元素时,-= 会移除它的第一个匹配项

val numbers = mutableListOf("one", "two", "three", "three", "four")
numbers -= "three"
println(numbers)
//第二个操作数可以包含集合中不存在的元素。这些元素不会影响操作的执行。
numbers -= listOf("four", "five")    
//numbers -= listOf("four")    // 与上述相同
println(numbers)    
结果:
[one, two, three, four]
[one, two, three]

更新元素

fill() 简单地将所有集合元素的值替换为指定值

val numbers = mutableListOf(1, 2, 3, 4)
numbers[1] =  9
println(numbers)
numbers.fill(3)
println(numbers)
结果:
[1, 9, 3, 4]
[3, 3, 3, 3]

List,Set,Map常用操作

List

get,[0],getOrNull,getOrElse,subList

取元素
getOrElse() 如果集合中不存在索引,则返回默认值。
getOrNull() 返回 null 作为默认值。

val numbers = listOf(1, 2, 3, 4)
println(numbers.get(0))
println(numbers[0])
//numbers.get(5)                         // exception!
println(numbers.getOrNull(5))             // null
println(numbers.getOrElse(5, {it}))  
结果:
1
1
null
5

取集合的一部分subList

val numbers = (0..13).toList()
println(numbers.subList(3, 6))
结果:
[3, 4, 5]
查找元素位置indexOf,lastIndexOf,indexOfFirst(),indexOfLast(),

indexOf() 或 lastIndexOf() 函数找到元素的位置。 它们返回与列表中给定参数相等的元素的第一个或最后一个位置

val numbers = listOf(1, 2, 3, 4, 2, 5)
println(numbers.indexOf(2))
println(numbers.lastIndexOf(2))
结果:
1
4
val numbers = mutableListOf(1, 2, 3, 4)
println(numbers.indexOfFirst { it > 2})
println(numbers.indexOfLast { it % 2 == 1})
结果:
2
2

binarySearch

Set

union(a union b),intersect(a intersect b),subtract(a subtract b)

并集: union(a union b)
交集:intersect(a intersect b)
差集:subtract(a subtract b)

val numbers = setOf("one", "two", "three")

println(numbers union setOf("four", "five"))
println(setOf("four", "five") union numbers)

println(numbers intersect setOf("two", "one"))
println(numbers subtract setOf("three", "four"))
println(numbers subtract setOf("four", "three")) // 相同的输出
结果:
[one, two, three, four, five]
[four, five, one, two, three]
[one, two]
[one, two]
[one, two]

Map

get(key),[key]:如果找不到给定的键,则返回 null
getValue() ,如果在 Map 中找不到键,则抛出异常。

getOrElse() 与 list 的工作方式相同:对于不存在的键,其值由给定的 lambda 表达式返回。
getOrDefault() 如果找不到键,则返回指定的默认值。

val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.get("one"))
println(numbersMap["one"])
println(numbersMap.getOrDefault("four", 10))
println(numbersMap["five"])               // null
//numbersMap.getValue("six")      // exception!
结果:
1
1
10
null

获取所有key和value

val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.keys)
println(numbersMap.values)
结果:
[one, two, three]
[1, 2, 3]
plus(+)与 minus(-)运算符
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap + Pair("four", 4))
println(numbersMap + Pair("one", 10))
println(numbersMap + mapOf("five" to 5, "one" to 11))
结果:
{one=1, two=2, three=3, four=4}
{one=10, two=2, three=3}
{one=11, two=2, three=3, five=5}
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap - "one")
println(numbersMap - listOf("two", "four"))
结果:
{two=2, three=3}
{one=1, three=3}
put,putAll 添加或修改,+=,set,[key]
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.put("three", 88)
numbersMap.putAll(setOf("three" to 99,"four" to 4, "five" to 5))
println(numbersMap)
结果:
{one=1, two=2, three=99, four=4, five=5}
val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap["three"] = 3     // 调用 numbersMap.set("three", 3)
numbersMap += mapOf("four" to 4, "five" to 5)
println(numbersMap)
结果:
{one=1, two=2, three=3, four=4, five=5}
删除条目

要从可变 Map 中删除条目,请使用 remove() 函数。 调用 remove() 时,可以传递键或整个键值对。 如果同时指定键和值,则仅当键值都匹配时,才会删除此的元素

val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.remove("one")
println(numbersMap)
numbersMap.remove("three", 4)            //不会删除任何条目
println(numbersMap)
结果:
{two=2, three=3}
{two=2, three=3}

还可以通过键或值从可变 Map 中删除条目。 在 Map 的 .keys 或 .values 中调用 remove() 并提供键或值来删除条目。 在 .values 中调用时, remove() 仅删除给定值匹配到的的第一个条目。

val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3, "threeAgain" to 3)
numbersMap.keys.remove("one")
println(numbersMap)
numbersMap.values.remove(3)
println(numbersMap)
结果:
{two=2, three=3, threeAgain=3}
{two=2, threeAgain=3}

-=

val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap -= "two"
println(numbersMap)
numbersMap -= "five"             //不会删除任何条目
println(numbersMap)
结果:
{one=1, three=3}
{one=1, three=3}

更多:
https://www.kotlincn.net/docs/reference/

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Kotlin是一种现代化的静态类型编程语言,它可以在Java虚拟机(JVM)上运行,并且与Java语言高度兼容。如果你想学习Kotlin,以下是一个学习路线的建议: 1. 了解基础知识:开始学习Kotlin之前,建议先了解一些基本的编程概念和语法,比如变量、数据类型、条件语句、循环语句等。这将为你后续的学习打下坚实的基础。 2. 学习Kotlin语法:Kotlin与Java有很多相似之处,但也有一些不同之处。学习Kotlin的语法和特性,比如空安全、扩展函数、数据类等,可以通过官方文档、教程或在线课程来学习。 3. 实践编程:通过编写一些简单的程序来巩固所学的知识。可以尝试解决一些小问题或者完成一些小项目,这样可以更好地理解和应用Kotlin的语法和特性。 4. 深入学习面向对象编程:Kotlin是一种面向对象的编程语言,深入学习面向对象编程的概念和原则对于掌握Kotlin非常重要。学习类、对象、继承、多态等概念,并尝试在Kotlin中应用这些概念。 5. 学习Kotlin与Java的互操作性:由于Kotlin与Java高度兼容,学习如何在Kotlin中使用Java类库和框架是非常重要的。了解如何调用Java代码、处理Java集合等,可以帮助你更好地使用Kotlin进行开发。 6. 深入学习Kotlin的高级特性:一旦掌握了Kotlin的基础知识,可以进一步学习一些高级特性,比如协程、函数式编程、DSL等。这些特性可以提高你的代码质量和开发效率。 7. 参与实际项目:最好的学习方式是通过实践。尝试参与一些实际的项目或者开源项目,与其他开发者合作,这样可以提升你的编程能力和实践经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦A梦z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值