Kotlin集合详解

《Kotlin集合详解》

  • List 是一个有序集合,可通过索引(反映元素位置的整数)访问元素。元素可以在 list 中出现多次。列表的一个示例是一句话:有一组字、这些字的顺序很重要并且字可以重复。
  • Set 是唯一元素的集合。它反映了集合(set)的数学抽象:一组无重复的对象。一般来说 set 中元素的顺序并不重要。例如,字母表是字母的集合(set)。
  • Map(或者字典)是一组键值对。键是唯一的,每个键都刚好映射到一个值。值可以重复。map 对于存储对象之间的逻辑连接非常有用,例如,员工的 ID 与员工的位置。

一.Collection

可以使用 Collection 作为适用于不同集合类型的函数的参数。对于更具体的情况,请使用 Collection 的继承者:ListSet

fun printAll(strings: Collection<String>) { 
        for(s in strings) print("$s ")
        println()
    }
    
fun main() { 
    val stringList = listOf("one", "two", "one")
    printAll(stringList)
    
    val stringSet = setOf("one", "two", "three")
    printAll(stringSet)
}
打印结果:
one two one 
one two three 

MutableCollection 是一个具有写操作的 Collection 接口,例如 add 以及 remove

fun List<String>.getShortWordsTo(shortWords: MutableList<String>, maxLength: Int) { 
    this.filterTo(shortWords) {  it.length <= maxLength }
    // throwing away the articles
    val articles = setOf("a", "A", "an", "An", "the", "The")
    shortWords -= articles
}

fun main() { 
    val words = "A long time ago in a galaxy far far away".split(" ")
    val shortWords = mutableListOf<String>()
    words.getShortWordsTo(shortWords, 3)
    println(shortWords)
}
打印日志:
[ago, in, far, far]

二.List

List元素(包括空值)可以重复

val numbers = listOf("one", "two", "three", "four")
println("Number of elements: ${ numbers.size}")
println("Third element: ${ numbers.get(2)}")
println("Fourth element: ${ numbers[3]}")
println("Index of element \"two\" ${numbers.indexOf("two")}")
打印结果:
Number of elements: 4
Third element: three
Fourth element: four
Index of element "two" 1

MutableList<T>是可以进行写操作的 List

val numbers = mutableListOf(1, 2, 3, 4)
numbers.add(5)
numbers.removeAt(1)
numbers[0] = 0
//打乱顺序
numbers.shuffle()
println(numbers)
打印结果:
[3, 5, 4, 0]

三.Set

Set<T> 存储唯一的元素;它们的顺序通常是未定义的。null元素也是唯一的:一个 Set 只能包含一个 null

val numbers = setOf(1, 2, 3, 4)
println("Number of elements: ${ numbers.size}")
if (numbers.contains(1)) println("1 is in the set")

val numbersBackwards = setOf(4, 3, 2, 1)
println("The sets are equal: ${ numbers == numbersBackwards}")
打印结果:
Number of elements: 4
1 is in the set
The sets are equal: true

MutableSet 是一个带有来自 MutableCollection 的写操作接口的 Set
Set的默认实现 – LinkedHashSet – 保留元素插入的顺序。

val numbers = setOf(1, 2, 3, 4)  // LinkedHashSet is the default implementation
val numbersBackwards = setOf(4, 3, 2, 1)

println(numbers.first() == numbersBackwards.first())
println(numbers.first() == numbersBackwards.last())
打印结果:
false
true

另一种实现方式 – HashSet – 不声明元素的顺序,所以在它上面调用这些函数会返回不可预测的结果。但是,HashSet 只需要较少的内存来存储相同数量的元素。

三.Map

Map<K, V>不是 Collection 接口的继承者;但是它也是 Kotlin 的一种集合类型。 Map存储 键-值 对(或 条目);键是唯一的,但是不同的键可以与相同的值配对。Map 接口提供特定的函数进行通过键访问值、搜索键和值等操作。

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

println("All keys: ${ numbersMap.keys}")
println("All values: ${ numbersMap.values}")
if ("key2" in numbersMap) println("Value by key \"key2\": ${numbersMap["key2"]}")    
if (1 in numbersMap.values) println("The value 1 is in the map")
if (numbersMap.containsValue(1)) println("The value 1 is in the map") // 同上
打印结果:
All keys: [key1, key2, key3, key4]
All values: [1, 2, 3, 1]
Value by key "key2": 2
The value 1 is in the map
The value 1 is in the map

无论键值对的顺序如何,包含相同键值对的两个 Map 是相等的。

MutableMap是一个具有写操作的 Map 接口,可以使用该接口添加一个新的键值对或更新给定键的值。

//映射的键和值作为 Pair 对象传递(通常使用中缀函数 to 创建)。
val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap.put("three", 3)
numbersMap["one"] = 11

println(numbersMap)
打印结果:
{ one=11, two=2, three=3}

//注意:to 符号创建了一个短时存活的 Pair 对象,因此建议仅在性能不重要时才使用它。 为避免过多的内存使用,请使用其他方法。例如,可以创建可写 Map 并使用写入操作填充它。 apply() 函数可以帮助保持初始化流畅。
val numbersMap2 = mutableMapOf<String, String>().apply {  this["one"] = "1"; this["two"] = "2" }

Map 的默认实现 – LinkedHashMap – 迭代 Map 时保留元素插入的顺序。 反之,另一种实现 – HashMap – 不声明元素的顺序。

五.集合遍历

iterator迭代器

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

for 循环

val numbers = listOf("one", "two", "three", "four")
for (item in numbers) { 
    println(item)
}

for (index in numbers.indices) { 
    println(numbers[index])
}

forEach()

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

指定区间迭代

if (i in 1..4) {   // 等同于 1 <= i && i <= 4
    print(i)
}

until

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

要反向迭代数字用downTo

for (i in 4 downTo 1) print(i)

通过任意步长迭代数字用step

for (i in 1..8 step 2) print(i)
println()
for (i in 8 downTo 1 step 2) print(i)

六.迭代器

1.List 迭代器

ListIterator 它支持列表双向迭代:正向与反向。
具有双向迭代的能力意味着 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()}")
}
打印结果:
Iterating backwards:
Index: 3, value: four
Index: 2, value: three
Index: 1, value: two
Index: 0, value: one

2.可变迭代器

val numbers = mutableListOf("one", "two", "three", "four") 
val mutableIterator = numbers.iterator()

mutableIterator.next()
mutableIterator.remove()    
println("After removal: $numbers")
打印结果:
After removal: [two, three, four]

除了删除元素, MutableListIterator 还可以在迭代列表时插入和替换元素。

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

mutableListIterator.next()
mutableListIterator.add("two")
mutableListIterator.next()
mutableListIterator.set("three")   
println(numbers)
打印结果:
[one, two, three, four]

七.集合转换

plusminus操作符

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

val plusList = numbers + "five"
val minusList = numbers - listOf("three", "four")
println(plusList)
println(minusList)
打印结果:
[one, two, three, four, five]
[one, two]

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}

count()maxOrNull()minOrNull()average()sum()

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

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

filter过滤操作符

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

val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits.filter {  it.startsWith("a") }
        .sortedBy {  it }
        .map {  it.toUpperCase() }
        .forEach {  println(it)    //集合遍历的方法 for-in forEach 迭代器遍历
打印结果:
APPLE
AVOCADO

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 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}

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)
打印结果:
[two, four]
[three, four]

filterIsInstance() 返回给定类型的集合元素

val numbers = listOf(null, 1, "two", 3.0, "four")
println("All String elements in upper case:")
numbers.filterIsInstance<String>().forEach { 
    println(it.toUpperCase())
}
打印结果:
All String elements in upper case:
TWO
FOUR

filterNotNull()返回所有的非空元素

val numbers = listOf(null, "one", "two", null)
numbers.filterNotNull().forEach { 
    println(it.length)   // 对可空的 String 来说长度不可用
}
打印结果:
3
3

map操作符

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

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]

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}

flatten()flatMap

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]

val containers = listOf(
    StringContainer(listOf("one", "two", "three")),
    StringContainer(listOf("four", "five", "six")),
    StringContainer(listOf("seven", "eight"))
)
println(containers.flatMap {  it.values })
打印结果:
[one, two, three, four, five, six, seven, eight]

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

val numbers = (1..100).toList()
//如果集合大小超出 limit,所有其他元素将被 truncated 参数的单个值替换。
println(numbers.joinToString(limit = 10, truncated = "<...>"))
打印结果:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, <...>

Slice操作符

val numbers = listOf("one", "two", "three", "four", "five", "six")    
println(numbers.slice(1..3))
println(numbers.slice(0..4 step 2))
println(numbers.slice(setOf(3, 5, 0)))    
打印结果:
[two, three, four]
[one, three, five]
[four, six, one]

zip操作符
zip()也可以中缀形式调用a zip b

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

val twoAnimals = listOf("fox", "bear")
println(colors.zip(twoAnimals))
打印结果:
[(red, fox), (brown, bear), (grey, wolf)]
[(red, fox), (brown, bear)]

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])

partition()划分

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

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

检验谓词anynoneall

val numbers = listOf("one", "two", "three", "four")
//any:至少有一个元素匹配给定谓词
println(numbers.any {  it.endsWith("e") })
//none:没有元素与给定谓词匹配
println(numbers.none {  it.endsWith("a") })
//all:所有元素都匹配给定谓词
println(numbers.all {  it.endsWith("e") })
打印结果:
true
true
false

Takedrop

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))
打印结果:
[one, two, three]
[four, five, six]
[two, three, four, five, six]
[one]

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 分块

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() })  // `it` 为原始集合的一个块
打印结果:
[3, 12, 21, 30, 25]

groupBy()分组

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]}

associateWith()associateByassociate

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.first().toUpperCase() })
println(numbers.associateBy(keySelector = {  it.first().toUpperCase() }, valueTransform = {  it.length }))
打印结果:
{ O=one, T=three, F=four}
{ O=3, T=5, F=4}

val names = listOf("Alice Adams", "Brian Brown", "Clara Campbell")
println(names.associate {  name -> parseFullName(name).let {  it.lastName to it.firstName } })
打印结果:
{ Adams=Alice, Brown=Brian, Campbell=Clara}

union:A元素 + B元素,A.addAll(B)的效果,但去重了
intersect(取交集)与 retainAll 功能相同:取A中和B相同的元素,即相同的输出
subtract:A中去掉和B相同的元素,即不相同的输出

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

println(numbers union setOf("four", "five"))// A元素 + B元素,A.addAll(B)的效果,但去重了
println(setOf("four", "five") union numbers)
println(numbers intersect setOf("two", "one"))// 取A中和B相同的元素,即相同的输出
println(numbers subtract setOf("three", "four"))// A中去掉和B相同的元素,不相同的输出
println(numbers subtract setOf("four", "three")) 
打印结果:
[one, two, three, four, five]
[four, five, one, two, three]
[one, two]
[one, two]
[one, two]

集合复制函数,例如toList()toMutableList()toSet() 等等

val sourceList = mutableListOf(1, 2, 3)
val copyList = sourceList.toMutableList()
val readOnlyCopyList = sourceList.toList()
sourceList.add(4)
println("Copy size: ${ copyList.size}")   

//readOnlyCopyList.add(4) // 编译异常
println("Read-only copy size: ${ readOnlyCopyList.size}")

val sourceList = mutableListOf(1, 2, 3)    
val copySet = sourceList.toMutableSet()
copySet.add(3)
copySet.add(4)    
println(copySet)

八.集合排序

sortsortDescending

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

numbers.sort()
println("Sort into ascending: $numbers")
numbers.sortDescending()
println("Sort into descending: $numbers")

numbers.sortBy {  it.length }
println("Sort into ascending by length: $numbers")
numbers.sortByDescending {  it.last() }
println("Sort into descending by the last letter: $numbers")
打印结果:
Sort into ascending: [four, one, three, two]
Sort into descending: [two, three, one, four]
Sort into ascending by length: [two, one, four, three]
Sort into descending by the last letter: [four, two, one, three]

compareTo()

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]

val numbers = mutableListOf("one", "two", "three", "four")
numbers.sortWith(compareBy<String> {  it.length }.thenBy {  it })
println("Sort by Comparator: $numbers")
打印结果:
Sort by Comparator: [one, two, four, three]

倒序
reversed() 返回带有元素副本的新集合
asReversed()返回相同集合实例,如果原始列表不会发生变化,那么它会比reversed() 更轻量,更合适

val numbers = listOf("one", "two", "three", "four")
println(numbers.reversed())
打印结果:
[four, three, two, one]
val numbers = listOf("one", "two", "three", "four")
val reversedNumbers = numbers.asReversed()
println(reversedNumbers)
打印结果:
[four, three, two, one]

随机顺序

val numbers = listOf("one", "two", "three", "four")
println(numbers.shuffled())
打印结果:
[three, one, two, four]
    原文作者:延成
    原文地址: https://blog.csdn.net/AliEnCheng/article/details/122979020
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞