Kotlin系列之集合的函数式API

几乎各种语言都对集合操作提供了方便的库函数,Kotlin也不例外,今天就来说说Kotlin中与集合操作相关的函数式API。

在开始之前先说一下这里的演示数据,后面演示数据的代码将不再重复出现:

//数字集合
val numList = listOf(1, 2, 3, 4, 5, 6)

//People数据类
data class People(val name: String, val age: Int)

val peopleList = listOf(People("小红", 22),
        People("小明", 23),
        People("小白", 22))

filter和map过滤变换

flitermap各种集合操作API的基础,如果你了解过Java8,应该对这两个函数不陌生,这里我们就不与Java8对比了,直接介绍他们在Kotlin中的用法。

filter是对一个集合中的所有元素应用一个表达式判断,然后返回一个判断结果为true的元素的新集合。说白了就是从一个集合中筛选出符合条件的元素并返回一个新集合。下面直接给出示例代码:

fun main(args: Array<String>) {
    //筛选出大于等于3的元素
    println(numList.filter { it >= 3 })

    //筛选出年龄等于22岁的人
    println(peopleList.filter { it.age == 22 })
}

如果对于代码中的Lambda表达式或者是数据类不了解的小伙伴,可以查看历史文章,这里就不再赘述了。

运行结果如下:

[3, 4, 5, 6]
[People(name=小红, age=22), People(name=小白, age=22)]

map是对一个集合中的每个元素应用一个表达式,然后生成一个新的集合,也是非常简单的,直接上代码:

fun main(args: Array<String>) {
    //求集合中每个元素的平方值
    println(numList.map { it * it })

    //提取出出集合中每个People对象的name属性
    println(peopleList.map { it.name })
}

运行结果如下:

[1, 4, 9, 16, 25, 36]
[小红, 小明, 小白]

当然上面的filtermap也可以链式调用,对一个集合做多次操作,比如我们想筛选出年龄等于22岁的人的姓名那就可以这样写:

fun main(args: Array<String>) {
    println(peopleList.filter { it.age == 22}.map { it.name })
}

输出结果如下:

[小红, 小白]

filtermap除了对list进行操作外,还可以操作map,注意这里的map是指key-value的map。看一下下面的代码分别对map的key和value进行过滤和变换操作。

fun main(args: Array<String>) {
    val numMap = mapOf("0" to 48, "1" to 49, "2" to 50, "3" to 51, "4" to 52)

    println(numMap.filter { it.key == "1" && it.value == 49 })
    println(numMap.filterKeys { it == "1" })
    println(numMap.filterValues { it == 48 })

    //返回一个list
    println(numMap.map { "key = " + it.key to "value = " + it.value})
    //返回一个新的map
    println(numMap.mapKeys { "key = " + it.key })
    //返回一个新的map
    println(numMap.mapValues { "value = " + it.value })
}

输出结果如下:

{1=49}
{1=49}
{0=48}
[(key = 0, value = 48), (key = 1, value = 49), (key = 2, value = 50), (key = 3, value = 51), (key = 4, value = 52)]
{key = 0=48, key = 1=49, key = 2=50, key = 3=51, key = 4=52}
{0=value = 48, 1=value = 49, 2=value = 50, 3=value = 51, 4=value = 52}

all、any、count和find查找

allanycountfind都是和查找相关的API。

all用来确定一个集合中的元素是否都满足某个条件,而any是判断集合中是否有元素满足某个条件。下面是示例代码:

fun main(args: Array<String>) {
    //判断是否所有元素都小于6
    println(numList.all { it <= 6 })

    //判断是否所有人的年龄都小于25岁
    println(peopleList.all { it.age < 25 })
    
    //判断是否存在大于100的数
    println(numList.any { it > 10 })

    //判断是否存在年龄大于25岁的人
    println(peopleList.any{ it.age > 25})
}

输出结果如下:

true
true
false
false

count用于对我们上面的判断检查进行统计,统计有多少个元素是满足条件的。就像下面这样:

fun main(args: Array<String>) {
    //统计集合中小于等于3的元素的个数
    println(numList.count { it <= 3 })

    //统计集合中年龄小于等于22的人的个数
    println(peopleList.count { it.age <= 22 })
}

输出结果如下:

3
2

其实上面的需求我们还有一种方式可以实现,就是先过滤出满足条件的元素组成一个新的集合,再获取这个新的集合的大小,就像下面这样:

fun main(args: Array<String>) {
    println(numList.filter { it <= 3 }.size)

    println(peopleList.filter { it.age <= 22 }.size)
}

上面的代码虽然可以完成我们的需求,但是它相较于前一种count的方式,生成了一个新的集合,其实我们根本不关心元素本身,所以count方式更加高效。

groupBy分组

groupBy用于对元素进行分组,分组后的结果是一个Map,它的类型是这样的Map<key, List>,如果你了解SQL,一定对groupBy不陌生。下面看看我们根据年龄对一个集合进行分组的代码示例:

fun main(args: Array<String>) {
    println(peopleList.groupBy { it.age })
}

输出结果如下:

{22=[People(name=小红, age=22), People(name=小白, age=22)], 23=[People(name=小明, age=23)]}

可以看出它的输出结果是Map<Int, List<People>>类型。

flatMap和flatten铺平

flatMapflatten的都是对集合的操作,你可以把它们简单理解为对集合元素进行展开再合并到一起形成一个新的集合。

其中flatMap是对一个集合进行map变换以后,再将变化后的多个集合合并为一个集合。如果你只是想单纯地合并多个集合而不需要变换,那就选用flatten,下面是具体的示例代码:

fun main(args: Array<String>) {
    val strList = listOf("abc", "def", "hij")
    println(strList.flatMap { it.toList() })

    val lists = listOf(listOf("abc", "bnm"), listOf("acv", "wnm"), listOf("awm"))
    println(lists.flatten())
}

输出结果如下:

[a, b, c, d, e, f, h, i, j]
[abc, bnm, acv, wnm]

是不是发现比我们手动合并多个集合方便多了。

写在最后

通过对Kotlin中集合操作API的介绍,又一次领略到Kotlin的简洁,以后遇到集合处理相关的需求,应该首先看看Kotlin是否已经提供了相关的API,然后选用合适的API进行处理即可。

已标记关键词 清除标记
限时福利1:原价 129 元,最后2天仅需 69 元!后天涨价至98元 限时福利2:购课进答疑群专享柳峰(刘运强)老师答疑服务 限时福利3:购课添加助教领取价值 800 元的编程大礼包 为什么需要掌握高性能的MySQL实战? 由于互联网产品用户量大、高并发请求场景多,因此对MySQL的性能、可用性、扩展性都提出了很高的要求。使用MySQL解决大量数据以及高并发请求已经是程序员的必备技能,也是衡量一个程序员能力和薪资的标准之一。 为了让大家快速系统了解高性能MySQL核心知识全貌,我为你总结了「高性能 MySQL 知识框架图」,帮你梳理学习重点,建议收藏! 【课程设计】 课程分为四大篇章,将为你建立完整的 MySQL 知识体系,同时将重点讲解 MySQL 底层运行原理、数据库的性能调优、高并发、海量业务处理、面试解析等。 一、性能优化篇: 主要包括经典 MySQL 问题剖析、索引底层原理和事务与锁机制。通过深入理解 MySQL 的索引结构 B+Tree ,学员能够从根本上弄懂为什么有些 SQL 走索引、有些不走索引,从而彻底掌握索引的使用和优化技巧,能够避开很多实战中遇到的“坑”。 二、MySQL 8.0新特性篇: 主要包括窗口函数和通用表表达。企业中的许多报表统计需求,如果不采用窗口函数,用普通的 SQL 语句是很难实现的。 三、高性能架构篇: 主要包括主从复制和读写分离。在企业的生产环境中,很少采用单台MySQL节点的情况,因为一旦单个节点发生故障,整个系统都不可用,后果往往不堪设想,因此掌握高可用架构的实现是非常有必要的。 四、面试篇: 程序员获得工作的第一步,就是高效的准备面试,面试篇主要从知识点回顾总结的角度出发,结合程序员面试高频MySQL问题精讲精练,帮助程序员吊打面试官,获得心仪的工作机会。
©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页