Kotlin集合详解

Kotlin集合详解,第1张

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是可以进行写 *** 作的 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 存储唯一的元素;它们的顺序通常是未定义的。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不是 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://outofmemory.cn/web/992389.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存