从0开始复习遍kotlin(集合 Collection)

本文详细介绍了Kotlin中集合的使用,包括List、Set、Map的基本操作,如构造、迭代、过滤、分组、排序、聚合等。讨论了如何创建、修改集合,以及如何利用函数如filter、map、joinToString等进行数据处理。此外,还涵盖了特定于列表的操作,如二分查找和元素定位。
摘要由CSDN通过智能技术生成

集合

一个集合通常包含多个相同类型的对象(这个数字也可能为零)
以下集合类型与 Kotlin 相关:

  • List是一个有序集合,可以通过索引访问元素 - 反映其位置的整数。元素可以在列表中出现多次。列表的一个例子是电话号码:它是一组数字,它们的顺序很重要,它们可以重复。
  • Set是独特元素的集合。它反映了集合的数学抽象:一组没有重复的对象。通常,集合元素的顺序没有意义。例如,彩票上的数字形成一个集合:它们是唯一的,它们的顺序并不重要。
  • Map(或字典)是一组键值对。键是唯一的,每个键都映射到一个值。这些值可以是重复的。地图对于存储对象之间的逻辑连接很有用,例如,员工的 ID 和他们的职位。

Kotlin 标准库提供基本集合类型的实现:集合、列表和映射。一对接口代表每种集合类型:

  • 一个只读接口,提供访问集合元素的操作。
  • 一个可变接口,它通过写操作扩展了相应的只读接口:添加、删除和更新其元素。
val numbers = mutableListOf("one", "two", "three", "four")
numbers.add("five")   // 成功
println(numbers)
//numbers = mutableListOf("six", "seven")      // 异常

Kotlin 集合接口的示意图:
在这里插入图片描述
Iterable : 迭代器
MutableIterable: 返回此序列元素的迭代器,该迭代器支持在迭代期间删除元素。
Collection : size,isEmpty(),contains(检查指定元素是否包含在此集合中。)containsAll,检查指定集合中的所有元素是否都包含在此集合中
MutableCollection:add,remove,addAll,removeAll,retainAll(仅保留此集合中包含在指定集合中的元素。)clear()
回报:
如果从集合中删除任何元素,则为 true;如果集合未被修改,则为 false。)
List:

  • 父类继承 size,isEmpty(),contains(检查指定元素是否包含在此集合中。)containsAll,(检查指定集合中的所有元素是否都包含在此集合中)
  • 子类特有 get,indexOf,lastIndexOf,listIterator(返回此列表中元素的列表迭代器(以正确的顺序)。)subList(集合截取,包头不包尾)

MutableList

  • 父类继承:add,remove,addAll,removeAll,retainAll(仅保留此集合中包含在指定集合中的元素。)clear(),get,indexOf,lastIndexOf,listIterator(返回此列表中元素的列表迭代器(以正确的顺序)。)subList(集合截取,包头不包尾)
  • 子类特有 removeAt

Set

  • 父类继承 size,isEmpty(),contains(检查指定元素是否包含在此集合中。)containsAll(检查指定集合中的所有元素是否都包含在此集合中.)

MutableSet
父类继承:add,remove,addAll,removeAll,retainAll(仅保留此集合中包含在指定集合中的元素。)clear()
Map
size,isEmpty(),containsKey(key),containsValue(value),get(key),getOrDefault(key,defaultValue),
keys(返回此映射中所有键的只读 Set。)
values(返回此映射中所有值的只读集合。 请注意,此集合可能包含重复值。)
entries(返回此映射中所有键/值对的只读 Set。)
MutableMap
put(),remove(key),putAll(Map),clear()
remove(key,value) 仅当映射到指定值时才删除指定键的条目。

集合构造

创建集合的最常见方法是使用标准库函数listOf()、setOf()、mutableListOf()、mutableSetOf()。如果您提供以逗号分隔的集合元素列表作为参数,编译器会自动检测元素类型。创建空集合时,明确指定类型。

val numbersSet = setOf("one", "two", "three", "four")
val emptySet = mutableSetOf<String>()

这同样适用于具有 和 功能的mapOf()地图mutableMapOf()。地图的键和值作为对象传递Pair(通常使用中to缀函数创建)。

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

to符号创建了一个短暂的Pair对象,因此建议您仅在性能不重要时使用它。为避免过度使用内存,请使用其他方法。例如,您可以创建一个可变映射并使用写入操作填充它。该apply()函数可以帮助在这里保持初始化流畅。

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

创建集合的另一种方法是调用构建器函数 - buildList()、buildSet()或buildMap()。他们创建一个新的、对应类型的可变集合,使用写操作填充它,并返回一个具有相同元素的只读集合:

val map = buildMap {  
    put("a", 1)
    put("b", 0)
    put("c", 4)
}

println(map) // {a=1, b=0, c=4}

空集合
还有用于创建不带任何元素的集合的函数:emptyList()、emptySet()和emptyMap()。创建空集合时,您应该指定集合将包含的元素类型。
具体类型构造函数
要创建具体的类型集合,例如ArrayListor LinkedList,您可以使用这些类型的可用构造函数。类似的构造函数可用于Set和的实现Map。

val linkedList = LinkedList<String>(listOf("one", "two", "three"))
val presizedSet = HashSet<Int>(32)

复制
要创建与现有集合具有相同元素的集合,您可以使用复制功能。标准库中的集合复制函数创建具有对相同元素的引用的浅拷贝集合。因此,对集合元素所做的更改会反映在其所有副本中。
集合复制函数,如toList()、等toMutableList(),toSet()在特定时刻创建集合的快照。他们的结果是相同元素的新集合。如果您在原始集合中添加或删除元素,这不会影响副本。副本也可以独立于来源进行更改。

val alice = Person("Alice")
val sourceList = mutableListOf(alice, Person("Bob"))
val copyList = sourceList.toList()
sourceList.add(Person("Charles"))
alice.name = "Alicia"
//sourceList[0] = Alicia copyList [0] = Alicia
//sourceList.size = 3  copyList.size = 2

这些函数也可用于将集合转换为其他类型,例如,从列表构建集合,反之亦然。

val sourceList = mutableListOf(1, 2, 3)    
val copySet = sourceList.toMutableSet()
copySet.add(3)
copySet.add(4)    
println(copySet)//[1, 2, 3, 4]
val sourceList = mutableListOf(1, 2, 3)
val referenceList = sourceList
referenceList.add(4)
println(sourceList)
println(referenceList)
println(sourceList === referenceList)
//[1, 2, 3, 4]
//[1, 2, 3, 4]
//true

可以通过对其他集合的各种操作来创建集合。例如,过滤列表会创建一个与过滤器匹配的新元素列表:

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

associateWith:将list转为map

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

迭代器

用来遍历集合元素

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)
}
val numbers = listOf("one", "two", "three", "four")
numbers.forEach {
    println(it)
}

List iterators

对于列表,有一个特殊的迭代器实现:ListIterator. 它支持双向迭代列表:向前和向后。
ListIterator.hasNext()。next() 向后.
listIterator.hasPrevious() previous()向前.

MutableIterator 可变迭代器

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

mutableListIterator.next()
mutableListIterator.add("two")
mutableListIterator.next()
mutableListIterator.set("three")   
println(numbers)

收集操作概述

Kotlin 标准库提供了各种各样的函数来对集合执行操作。这包括简单的操作,例如获取或添加元素,以及更复杂的操作,包括搜索、排序、过滤、转换等。

常用操作

集合转换

map

非空判断

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

单独key操作

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
println(numbersMap.mapKeys { it.key.uppercase() })
println(numbersMap.mapValues { it.value + it.key.length })
zip

集合合并

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

val twoAnimals = listOf("fox", "bear")
println(colors.zip(twoAnimals))//[(red, fox), (brown, bear)]
list转map

基本关联函数associateWith()创建一个Map,其中原始集合的元素是键,值由给定的转换函数从它们产生。

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

associateBy()创建一个Map,自定义key,值为list的值。

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

println(numbers.associateBy { it.first().uppercaseChar() })
println(numbers.associateBy(keySelector = { it.first().uppercaseChar() }, valueTransform = { it.length }))
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)//[one, two, three, four]         
println(numbers.joinToString())//one, two, three, four
//添加字符
val listString = StringBuffer("The list of numbers: ")
numbers.joinTo(listString)
println(listString)//The list of numbers: one, two, three, four

构建自定义字符串表示,您可以在函数参数separator、prefix和中指定其参数postfix。生成的字符串将以 开头,以.prefix结尾postfix。将separator出现在除最后一个元素之外的每个元素之后。

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, <...>

Filter 过滤

val numbers = listOf("one", "two", "three", "four")  
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3)
//[three, four]
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)
//{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)//[two, four]
println(filteredNot)//[three, four]

Partition
match 返回过滤后的数据
rest 返回被删选掉的数据

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

println(match)//[three, four]
println(rest)//[one, two]
  • any()如果至少一个元素与给定的谓词匹配,则返回true。
  • none() 如果没有任何元素与给定的谓词匹配,则返回true。
  • all() 如果所有元素都匹配给定的谓词,则返回true。
val numbers = listOf("one", "two", "three", "four")

println(numbers.any { it.endsWith("e") })//true
println(numbers.none { it.endsWith("a") })//true
println(numbers.all { it.endsWith("e") })//false

any()并且none()也可以在没有谓词的情况下使用:在这种情况下,他们只是检查集合是否为空。

分组

  • eachCount()计算每组中的元素。
val numbers = listOf("one", "two", "three", "four", "five")

println(numbers.groupBy { it.first().uppercase() })
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.uppercase() }))
//{O=[one], T=[two, three], F=[four, five]}
//{o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}

Slice 集合分割

val numbers = listOf("one", "two", "three", "four", "five", "six")    
println(numbers.slice(1..3))//截取1-3
println(numbers.slice(0..4 step 2))//截取0-4 并跳过2
println(numbers.slice(setOf(3, 5, 0))) //取 35,0
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.take(3))//取前三
println(numbers.takeLast(3))//取后三
println(numbers.drop(1))//去除前1
println(numbers.dropLast(5))//去除后5
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.takeWhile { !it.startsWith('f') })//从0开始到首字母为f
println(numbers.takeLastWhile { it != "three" })//从最后开始到== three
println(numbers.dropWhile { it.length == 3 })//去除从0开始到第一个长度等于3的。
println(numbers.dropLastWhile { it.contains('i') })//从末尾开始去除包含i的。

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 = listOf("one", "two", "three", "four", "five")    
println(numbers.windowed(3))
//[[one, two, three], [two, three, four], [three, four, five]]
val numbers = (1..10).toList()
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() 获取特定位置元素
  • first() 获取第一个
  • last() 获取最后一个
    first()后接lamda表达添加条件
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.first { it.length > 3 })
println(numbers.last { it.startsWith("f") })
  • elementAtOrNull() 获取特定位置元素 没有返回null
  • elementAtOrElse()获取特定位置元素 没有返回Else
  • random() 随机获取集合内数据
  • 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")))
  • isEmpty() 是否为空。

Ordering

在 Kotlin 中,可以通过多种方式定义对象的顺序。
自然秩序是为Comparable接口的实现而定义的。当没有指定其他顺序时,使用自然顺序对它们进行排序。

  • 数值类型使用传统的数值顺序:1大于0;-3.4f大于-5f,以此类推。
  • Char并String使用字典顺序:b大于a;world大于hello。

**要为用户定义的类型定义自然顺序,请将该类型设为Comparable. 这需要实现该compareTo()功能。compareTo()必须将另一个相同类型的对象作为参数,并返回一个整数值,显示哪个对象更大:
**

  • 正值表示接收对象更大。
  • 负值表明它小于参数。
  • 零表示对象相等。

使用Comparator()自定义排序规则

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

compareBy()接受一个 lambda 函数,该函数从实例中生成一个Comparable值,并将自定义顺序定义为生成值的自然顺序。

println(listOf("aaa", "bb", "c").sortedWith(compareBy { it.length }))
//[c, bb, aaa]

sorted() 自然排序。
sortedBy() 根据自定义条件排序。
reversed() 集合反转。返回新集合。
asReversed() 返回同一集合反转数据。

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

shuffled() 已随机顺序返回一个包含集合元素的新集合-

Aggregate operations 聚合操作


   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()}")//总数

  • maxByOrNull() and minByOrNull() 通过附加条件的最大值与最小值
  • maxWithOrNull()并minWithOrNull()取一个Comparator对象并根据它返回最大或最小的元素Comparator。
  • maxOfOrNull()并minOfOrNull()取一个选择器函数并返回选择器本身的最大或最小返回值。
  • maxOfWithOrNull()并minOfWithOrNull()取一个Comparator对象并根据它返回最大或最小的选择器返回值Comparator。
  • sumOf 值附加条件后在求和
val numbers = listOf(2, 4, 2, 2)
println(numbers.sumOf { it * 2 })
//20

reduce():sum:每次相加总数结果。element :数组元素。
fold(initial):initial:初始值,写0效果等同于reduce()。sum:每次相加总数结果。element :数组元素。

val numbers = listOf(5, 2, 10, 4)
val simpleSum = numbers.reduce { sum, element -> 
    sum + element
}

集合写操作

添加元素
addAll() 添加全部

val numbers = mutableListOf(1, 2, 3, 4)
numbers.add(5)
println(numbers)

removing()删除

val numbers = mutableListOf(1, 2, 3, 4, 3)
numbers.remove(3)                  
println(numbers)

removeAll()传入一个集合 删除集合内的所有元素。
retainAll() 保留符合条件的元素。
clear() 删除所有。

特定于列表的操作

  • getOrElse()如果集合中不存在索引,则允许您提供计算要返回的默认值的函数。
  • getOrNull()null作为默认值返回。
val numbers = listOf(1, 2, 3, 4)
println(numbers.get(0))
println(numbers[0])
//numbers.get(5)                         // exception!
println(numbers.getOrElse(5, {7}))        // 7

检索部分列表

val numbers = (0..13).toList()
println(numbers.subList(3, 6))
//[3, 4, 5]

查找元素位置

  • indexOf()返回等于列表中给定参数的元素的第一个索引。
  • lastIndexOf()返回等于列表中给定参数的元素的最后一个索引。
  • indexOfFirst()返回与谓词匹配的第一个元素的索引,-1或者如果没有这样的元素。
  • indexOfLast()返回与谓词匹配的最后一个元素的索引,-1或者如果没有这样的元素。
    二分搜索
    binarySearch() 需要根据特定顺序对列表进行升序排序:自然或函数参数中提供的另一种顺序。否则,结果是未定义的。
    要搜索排序列表中的元素,请调用binarySearch()将值作为参数传递的函数。如果存在这样的元素,则函数返回其索引;否则,它返回(-insertionPoint - 1)whereinsertionPoint是应该插入此元素的索引,以便列表保持排序。如果具有给定值的元素不止一个,则搜索可以返回它们的任何索引。
val numbers = mutableListOf("one", "two", "three", "four")
numbers.sort()
println(numbers)
println(numbers.binarySearch("two"))  // 3
println(numbers.binarySearch("z")) // -5
println(numbers.binarySearch("two", 0, 2))  // -3

比较二分查找
当列表元素不是Comparable时,您应该提供一个Comparator在二分搜索中使用。列表必须根据 this 升序排列Comparator

val productList = listOf(
    Product("WebStorm", 49.0),
    Product("IOSCode", 99.0),
    Product("AppCode", 99.0),
    Product("DotTrace", 129.0),
    Product("ReSharper", 149.0))

println(productList.binarySearch(Product("AppCode", 99.0), compareBy<Product> { it.price }.thenBy { it.name }))
//2 先比较price,在比较name.
  • add()
val numbers = mutableListOf("one", "five", "six")
numbers.add(1, "two")
numbers.addAll(2, listOf("three", "four"))
println(numbers)
  • 列表还提供了在给定位置替换元素的功能 -set()及其运算符形式[]。set()不会更改其他元素的索引。
val numbers = mutableListOf("one", "five", "three")
numbers[1] =  "two"
println(numbers)
  • fill() simply replaces all the collection elements with the specified value.
val numbers = mutableListOf(1, 2, 3, 4)
numbers.fill(3)
println(numbers)
  • remove
val numbers = mutableListOf(1, 2, 3, 4, 3)    
numbers.removeAt(1)
println(numbers)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值