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
 

一、声明可变集合

二、声明不可变集合

通过 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 扩展函数分析 )

Kotlin 初学者集合

Kotlin 初学者集合

Kotlin——数组

kotlin-----集合list、map和set