写一篇好懂的常见Kotlin集合函数讲解(中)

837 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情

本文主要介绍kotlin集合使用频率较高的函数,灵活的使用它们能帮助程序提高开发效率,减少模板代码 历史文章:写一篇好懂的常见Kotlin集合函数讲解(前)

any{}: 查找集合只要存在指定条件的元素就返回true

我们经常会遇见一种场景:遍历集合,只要某个元素符合指定条件就立刻返回为true:

fun any(): Boolean {
    val list = listOf(3, 4, 6, 5, 2)
    for (i in list) {
        if (i == 5) {
            return true
        }
    }
    return false
}

这样写太太麻烦了,使用any改写为:return list.any { it == 5 }

该函数还有其他相似函数:

  • all{}:查找集合只有集合中所有元素都符合指定条件才返回true

fold(){}:带有初始值的叠加器,如果集合为空返回的将是传入的初始值

我们实现一个n!(n的阶乘):

fun fold(n: Int): Int =
    (1..n).fold(1) { acc, next ->
        acc * next
    }

第一次叠加的过程中,acc就是初始值1,next就是集合的第一个元素,计算出的acc * next就是下一次叠加的acc,下一次的next也就是集合的第二个元素,依次类推...

其他相似函数:

  • reduce:不带初始值的叠加器,其中第一次叠加的acc就是集合的第一个元素,next就是集合的第二个元素,依次类推...
  • foldIndexed{}/reduceIndexed{}:和上面的区别就只是带了索引

joinToString:将集合按照一定格式转化为字符串

比如将集合转换成字符串并使用","作为集合元素间的分隔符:

fun join() {
    val list = listOf("aa", "bf", "gd", "et")
    val result = list.joinToString(",")
    
    //输出:aa,bf,gd,et
}

还可以给集合转换后的字符串分别增加前缀和后缀:

list.joinToString(",", "pre", "post")

//输出:preaa,bf,gd,etpost

集合转换成字符串的过程中,可以对集合的每个元素映射成的字符串内容进行处理:

list.joinToString(",") {
    "$it  haha"
}
//输出:aa  haha,bf  haha,gd  haha,et  haha

binarySearch:二分查找指定条件的元素

相比较于find系列的操作符,查找的效率更高,时间复杂度为lognlogn(以2为底) ,如果查找不到就返回-1。

举个例子,二分查找集合中是否存在某个整数(前提是要集合有序)

fun binarySearch() {
    val list = listOf(3, 5, 7, 9, 33, 66, 88, 99)
    println(list.binarySearch {
        when {
            it == 66 -> 0
            it < 66 -> -1
            it > 66 -> 1
            else -> 0
        }
    })
}
//输出:5

asReversed:集合倒序

val list = listOf(3, 5, 7, 9, 33, 66, 88, 99)
println(list.asReversed())
//输出:[99, 88, 66, 33, 9, 7, 5, 3]

elementAt(index):根据索引获取集合元素,和get[index]一样,index小于0或者越界抛出异常

其他相似集合:

  • elementAtOrElse(){}:根据索引获取元素,当传入的索引小于0或者超过集合长度时,采取传入的函数类型生成结果值
  • elementAtOrNull():根据索引获取元素,当传入的索引小于0或者超过集合长度时,返回为null

slice(IntRange/Iterable<Int>):返回指定索引对应集合元素

相比较传统的subList获取的是一段索引连续的元素元素,而slice则是能灵活指定任意数量的具体索引(可以非连续)并返回对应的元素集合:

val list = listOf(3, 5, 7, 9, 33, 66, 88, 99)
println(list.slice(listOf(3, 5, 6)))
//输出:[9, 66, 88]