Kotlin集合简介
Posted 古月书斋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin集合简介相关的知识,希望对你有一定的参考价值。
本文整理自:https://chiclaim.blog.csdn.net/article/details/85575213
Kotlin 中的集合底层也是使用 Java 集合框架那一套。在上层又封装了一层 可变集合 和 不可变集合 接口。
下面是 Kotlin 封装的可变集合和不可变集合接口:
接口 是否可变 所在文件
List 不可变 Collections.kt
MutableList 可变 Collections.kt
Set 不可变 Collections.kt
MutableSet 可变 Collections.kt
Map 不可变 Collections.kt
MutableMap 可变 Collections.kt
一、声明可变集合
![](https://image.cha138.com/20220729/1dc98f82ea674458bef2d9243857aa78.jpg)
二、声明不可变集合
通过 Kotlin 提供的 API 可以方便的创建各种集合,但是同时需要搞清楚该 API 创建的集合底层到底是对应 Java 的哪个集合。
三、Kotlin 集合常用的 API
1) all、any、count、find、firstOrNull、groupBy 函数
2) filter、map、flatMap、flatten 函数
案例分析:list.map(Person::age).filter it > 18
虽然 list.map(Person::age).filter it > 18 代码非常简洁,我们要知道底层做了些什么?反编译代码如下:
发现调用 map 和 filter 分别创建了一个集合,也就是整个操作创建了两个 2 集合。
四、延迟集合操作之 Sequences
根据上面的分析,list.map(Person::age).filter it > 18
会创建两个集合,本来常规操作一个集合就够了,Sequence就是就是为了避免创建多余的集合的问题。
val list = listOf<Person>(Person("chiclaim", 18), Person("yuzhiqiang", 15),
Person("johnny", 27), Person("jackson", 190),
Person("pony", 85))
//把 filter 函数放置前面,可以有效减少 map 函数的调用次数
list.asSequence().filter person ->
println("filter---> $person.name : $person.age")
person.age > 20
.map person ->
println("map----> $person.name : $person.age")
person.age
.forEach
println("---------符合条件的年龄 $it")
为了提高效率,我们把 filter 调用放到了前面,并且加了一些测试输出:
filter---> chiclaim : 18
filter---> yuzhiqiang : 15
filter---> johnny : 27
map----> johnny : 27
---------符合条件的年龄 27
filter---> jackson : 190
map----> jackson : 190
---------符合条件的年龄 190
filter---> pony : 85
map----> pony : 85
---------符合条件的年龄 85
从这个输出日志我们可以总结出 Sequence 的原理:
集合的元素有序的经过 filte r操作,如果满足 filter 条件,再经过 map 操作。
而不会新建一个集合存放符合 filter 条件的元素,然后在创建一个集合存放 map 的元素
Sequence 的原理图如下所示:
需要注意的是,如果集合的数量不是特别大,并不建议使用 Sequence 的方式来进行操作。我们来看下 Sequence<T>.map
函数
public fun <T, R> Sequence<T>.map(transform: (T) -> R): Sequence<R>
return TransformingSequence(this, transform)
它是一个高阶函数,但是它并没有内联,为啥没有内联?因为它把 transform 传递给了 TransformingSequence,然后TransformingSequence通过属性将其保存起来了,并没有直接使用 transform,所以不能内联。
根据上面我们对高阶函数的分析,如果一个高阶函数没有内联,每调用一次该函数都会创建内部类。
除此之外还有一点也需要注意,下面一段代码实际上不会执行:
list.asSequence().filter person ->
person.age > 20
.map person ->
person.age
只有用到了该 Sequence 里的元素才会触发上面的操作,比如后面调用了 forEach、toList 等操作。
对 Sequence 做一个小结:
如果集合的数据量很大啊,可以使用集合操作的延迟 Sequence
Sequence 的 filter、map 等扩展还是是一个非 inline 的高阶函数
集合的 Sequence 只有调用 forEach、toList 等操作,才会触发对集合的操作。有点类似 RxJava。
以上是关于Kotlin集合简介的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin函数式编程 ③ ( 早集合与惰性集合 | 惰性集合-序列 | generateSequence 序列创建函数 | 序列代码示例 | take 扩展函数分析 )
Kotlin函数式编程 ③ ( 早集合与惰性集合 | 惰性集合-序列 | generateSequence 序列创建函数 | 序列代码示例 | take 扩展函数分析 )