Kotlin学习笔记(二)集合

本来这节不应该放这里的,因为在公司做一个小项目练手的时候碰到了些坑,使用了一个List,结果怎么也找不到添加item的方法,就先恶补了一下。
  首先Kotlin中的集合具有可变性和不可变性的区别,来看一下Kotlin中的相关接口:

Iterable MutableIterable
Collection MutableCollection
List MutableList
Set MutableSet
Map MutableMap

首先说明一下,这个表格并不代表继承关系,只是区分可变不可变。继承关系如下图,原谅我画的比较丑:

Kotlin学习笔记(二)集合_第1张图片
Kotlin集合继承关系.jpg
  • Iterable:父类。所有可以遍历的集合都是实现这个接口。只声明了iterator()一个方法,返回一个Iterator。
  • MutableIterable:重写了父类的iterator()方法,返回一个MutableIterable。
  • Collection:这个类是一个范性集合。仅包含集合是否为空,是否包含某元素等几个方法,有兴趣的可以看源码,是只读集合,不可变。
  • MutableCollection:在Collection的基础上提供了额外的函数,比如 add 、 remove 、 clear 等等,是可变集合。
  • List:它是一个范性有序的集合。因为它的有序,我们可以使用 get 函数通过position来访问,继承于Collection,只读集合。
  • MutableList:一个支持增加和删除item的List,可变集合。
  • Set:一个无序并不支持重复item的集合。
  • MutableSet:一个支持增加和删除item的Set。
  • Map:一个key-value对的集合。key在map中是唯一的,也就是说不能有两对key是一样的键值对存在于一个map中。
  • MutableMap:一个支持增加和删除item的map。增加了put和remove方法。
      附上源码中的结构图:
Kotlin学习笔记(二)集合_第2张图片
1.png
Kotlin学习笔记(二)集合_第3张图片
2.png
Kotlin学习笔记(二)集合_第4张图片
3.png
Kotlin学习笔记(二)集合_第5张图片
4.png

另外,kotlin中封装了很多常用的操作符,学会使用的话可以节省我们很多的代码量。

总数操作符

any
如果至少有一个元素符合给出的判断条件,则返回true。
all
如果全部的元素符合给出的判断条件,则返回true。
count
返回符合给出判断条件的元素总数。
fold
在一个初始值的基础上从第一项到最后一项通过一个函数累计所有的元素。
foldRight
与 fold 一样,但是顺序是从最后一项到第一项。
forEach
遍历所有元素,并执行给定的操作。
forEachIndexed
与 forEach 类似,但是我们同时可以得到元素的index。类似的还有foldIndexed和foldRightIndexed。
max
返回最大的一项,如果没有则返回null。min同理。
maxBy
根据给定的函数返回最大的一项(返回的是集合本身的元素,而非给定函数运算过结果),如果没有则返回null。minBy同理。
none
如果没有任何元素与给定的函数匹配,则返回true。
reduce
reduce系列类似fold系列,包括reduceIndexed、reduceRight、reduceRightIndexed,只是没有初始值。
sumBy
返回所有每一项通过函数转换之后的数据的总和。

    val list = listOf(1, 2, 3, 4, 5, 6)

    println(list.any { it > 5 })//true
    println(list.all { it > 1 })//false
    println(list.count { it > 3 })//3
    println(list.fold(5) { total, next -> total + next })//5+1+2+3+4+5+6=26
    println(list.fold(5) { total, next -> total * next })//5*1*2*3*4*5*6=3600
    println(list.fold("5") { total, next -> total + next })//"5"+1+2+3+4+5+6="5123456"
    println(list.foldRight(5) { total, next -> total + next })//"5"+1+2+3+4+5+6="5123456"
    list.forEach { print(it) }//123456
    list.forEachIndexed { index, i -> print("$index:$i,") }//0:1,1:2,2:3,3:4,4:5,5:6,
    println(list.max())//6
    println(list.maxBy { it * -1 })//1
    println(list.none { it > 6 })//true
    println(list.reduce { acc, i -> acc + i })//21
    println(list.sumBy { it * -1 })//-21

过滤操作符

drop
返回去掉前n个元素的剩余元素的列表。
dropLast
返回去掉后n个元素的剩余元素的列表。
dropWhile
返回根据给定函数从第一项开始去掉指定元素的列表。即从前面开始,符合条件的一律去除,直到碰到一个不符合条件的元素为止。
dropLastWhile
返回根据给定函数从最后一项开始去掉指定元素的列表。
filter
过滤所有符合给定函数条件的元素。filterIndexed同filter,同时返回索引。
filterNot
过滤所有不符合给定函数条件的元素。
filterNotNull
过滤所有元素中不是null的元素。
slice
过滤一个list中指定index的元素。
take
返回从第一个开始的n个元素。takeLast从最后一个开始返回n个。
takeWhile
返回从第一个开始符合给定函数条件的元素,一旦不符合即停止。takeLastWhile从最后一个开始返回。
takeIf
如果满足条件,则返回这个集合,注意参数it代表的是集合,而非集合中的元素。takeUnless相反,如果满足条件,则返回null,否则返回集合本身。

    val list = listOf(1, 2, 3, 4, 5, 6)
    println(list.drop(2))//[3, 4, 5, 6]
    println(list.dropLast(2))//[1, 2, 3, 4]
    println(list.dropWhile { it > 2 })//[1, 2, 3, 4, 5, 6]
    println(list.dropLastWhile { it > 2 })//[1, 2]
    println(list.filter { it > 3 })//[4, 5, 6]
    println(list.filterIndexed { index, i -> i > 3 && index > 4 })//[6]
    println(list.filterNot { it > 3 })//[1, 2, 3]
    println(list.filterNotNull())//[1, 2, 3, 4, 5, 6]
    println(list.slice(1..2))//[2, 3]
    println(list.take(3))//[1, 2, 3]
    println(list.takeLast(3))//[4, 5, 6]
    println(list.takeWhile { it > 3 })//[]
    println(list.takeLastWhile { it > 3 })//[4, 5, 6]
    println(list.takeIf { it.isNotEmpty() })//[1, 2, 3, 4, 5, 6]
    println(list.takeUnless { it.isNotEmpty() })//null

映射操作符

flatMap
遍历所有的元素,为每一个创建一个集合,最后把所有的集合放在一个集合中。
groupBy
返回一个根据给定函数分组后的map。
map
返回一个每一个元素根据给定的函数转换所组成的List。mapIndexed同理,同时可以操作每一个元素的索引。
mapNotNull
返回一个每一个非null元素根据给定的函数转换所组成的List。mapIndexedNotNull同理。

    val list = listOf(1, 2, 3, 4, 5, 6)
    println(list.flatMap { listOf(it + 1) })//[2, 3, 4, 5, 6, 7]
    println(list.groupBy { it % 2 == 0 })//{false=[1, 3, 5], true=[2, 4, 6]}
    println(list.map { it * it })//[1, 4, 9, 16, 25, 36]
    println(list.mapNotNull { it?.times(2) })//[2, 4, 6, 8, 10, 12],如果list改为listOf(1, 2, 3, 4, 5, null),则返回[2, 4, 6, 8, 10]

元素操作符

contains
如果指定元素可以在集合中找到,则返回true。
elementAt
返回给定index对应的元素,如果index数组越界则会抛出 IndexOutOfBoundsException 。
elementAtOrElse
返回给定index对应的元素,如果index数组越界则会根据给定函数返回默认值。
elementAtOrNull
返回给定index对应的元素,如果index数组越界则会返回null。
first
返回符合给定函数条件的第一个元素。
firstOrNull
返回符合给定函数条件的第一个元素,如果没有符合则返回null。
indexOf
返回指定元素的第一个index,如果不存在,则返回 -1 。
indexOfFirst
返回第一个符合给定函数条件的元素的index,如果没有符合则返回 -1 。
indexOfLast
返回最后一个符合给定函数条件的元素的index,如果没有符合则返回 -1 。
last
返回符合给定函数条件的最后一个元素。
lastIndexOf
返回指定元素的最后一个index,如果不存在,则返回 -1 。
lastOrNull
返回符合给定函数条件的最后一个元素,如果没有符合则返回null。
single
返回符合给定函数的单个元素,如果没有符合或者超过一个,则抛出异常。
singleOrNull
返回符合给定函数的单个元素,如果没有符合或者超过一个,则返回null。
  这一部分与java中的集合操作类似,基本看字面就可以理解什么意思,应该也是最常用的一些操作符了。

生产操作符

partition
把一个给定的集合分割成两个,第一个集合是由原集合每一项元素匹配给定函数条件返回 true 的元素组成,第二个集合是由原集合每一项元素匹配给定函数条件返回 false 的元素组成。
plus
返回一个包含原集合和给定集合中所有元素的集合,因为函数的名字原因,我们可以使用 + 操作符。
zip
返回由 pair 组成的List,每个 pair 由两个集合中相同index的元素组成。这个返回的List的大小由最小的那个集合决定。
unzip
从包含pair的List中生成包含List的Pair。

    val list1 = listOf(1, 2, 3)
    val list2 = listOf(4, 5, 6)
    println(list1.partition { it % 2 == 0 })//([2], [1, 3])
    println(list1.plus(list2))//[1, 2, 3, 4, 5, 6]
    println(list1 + list2)//[1, 2, 3, 4, 5, 6]
    println(list1.zip(list2))//[(1, 4), (2, 5), (3, 6)]
    println(listOf(Pair(1, 2), Pair(3, 4)).unzip())//([1, 3], [2, 4])

顺序操作符

reverse
返回一个与原list反序的list。
sort
返回一个原list升序排列后的list。
sortBy
返回一个根据指定函数升序排序后的list。
sortDescending
返回一个原list降序排序后的List。
sortDescendingBy
返回一个根据指定函数降序排序后的list。

    val list = listOf(1, 2, 3, 4, 5, 6)
    println(list.reversed())//[6, 5, 4, 3, 2, 1]
    println(list.sorted())//[1, 2, 3, 4, 5, 6]
    println(list.sortedBy { it % 6 })//[6, 1, 2, 3, 4, 5]
    println(list.sortedDescending())//[6, 5, 4, 3, 2, 1]
    println(list.sortedByDescending { it % 6 })//[5, 4, 3, 2, 1, 6]

注意上述所有操作符的测试环境为List,而非MutableList,即上述操作符并不会改变原集合本身。

你可能感兴趣的:(Kotlin学习笔记(二)集合)