Kotlin第十二讲---高阶函数

内容简介

说实话,当我在次看见高阶函数的时候,我都纳闷了?啥是高阶函数呢?网上查了查好像没有特别的定义。网上有人定义为 将函数当做参数或者返回值的函数,好吧。。。就这么认为吧。回想下前面讲的 作用域函数 好像也是高阶函数哦。

常用的高阶函数

试想下,这样函数的超级多,定义也相当简单。因为 kotlin 是支持函数可以变成参数的形式传递(想想前面讲的函数为何能传递呢?友情提醒 FunctionN 对象)。

Kotlin 为我们提供了很多高阶函数,一般都是以扩展函数的形式去定义的。当然我们也可以自己定义高阶函数,这里就说下我知道的几个吧,这样的函数太多了,大家自己去看看源码。

友情提醒:个人认为,自己定义的高阶函数若经常使用,可以使用 inline (内联函数)修饰,减少不必要的对象创建开销。

forEach

遍历每个元素,源码太简单啦,自行脑补吧!!

fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    /**
     * 遍历每个元素
     */
    arrays.forEach {
    }
}

map

和 RxJava 的一样,对每个数据进行转换,并返回新的数据集合。 kotlin 天生支持函数式编程的哦(原理就是牛X的扩展方法)。

fun main() {
    val arrays = arrayOf("1", "2", "3", "4")
    /**
     * 遍历每个元素
     */
    val map = arrays.map {
        it.toInt()
    }
    /**
     * 遍历
     */
    map.forEach(::println)
}

floatMap

和 RxJava 有点不同,遍历集合每个元素,每个元素调用一次 Lambda 表达式且返回一个集合,最终整合在一个集合中返回。

fun main() {
    val arrays = arrayOf("1,2,3", "2,3,4", "3,2", "4,3")
    val flatMap = arrays.flatMap {
        it.split(",").map { it.toInt() }
    }
    /**
     * 遍历
     */
    flatMap.forEach(::println)
}

fold

给定一个一个初始值,传入 Lambda 表达式第一个参数就是上次元素返回的结果,大家看看源码吧,这个不是很好解释。

我这个功能就是做了一个字符串数组求和。

fun main() {
    val arrays = arrayOf("1", "2", "3", "4")
    val fold = arrays.fold(0) { acc, s ->
        acc + s.toInt()
    }
    println(fold)
}

sumBy

其实上面我通过 fold 做了一个字符串数组求和的实例,不过使用 sumBy 更为的适合这个例子。就是遍历其每个元素,传入的 Lambda 表达返回一个 Int 并求和(看源吗吧,瞜一眼便知)。

fun main() {
   val arrays = arrayOf("1", "2", "3", "4")
   arrays.sumBy {
      it.toInt()
   }.let(::println)
}

reduce

这个和上面的 fold 类似,但是无需传入初始值了,初始值变成了数组的第一个元素(注意这个遍历就跳过了第一个元素哦)

/**
 * 继续求和
 */
fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    val reduce = arrays.reduce { acc, s ->
        acc + s
    }
    println(reduce)
}

filter

过滤元素,只有 Lambda 表达式返回 ture,才会加入返回集合当中。

fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    val filter = arrays.filter {
        it % 2 == 0
    }
    filter.forEach(::println)
}

all

集合中,所有元素满足 Lambda 条件,返回 ture,否则返回 false

fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    val all = arrays.all {
        it > 2
    }
    println(all)
}

any

集合中,有任意一个元素,满足 Lambda 条件返回 true

fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    val all = arrays.all {
        it > 2
    }
    println(all)
}

count

满足 Lambda 表达式条件的元素个数。

fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    val all = arrays.count {
        it > 2
    }
    println(all)
}

find & findLast

find 是在集合中查找第一个 Lambda 返回 true 的元素,并返回。而 findLast 是在集合中查找最后一个 Lambda 返回 true 的元素。

查找不到返回 null

fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    val find = arrays.find {
        it > 2
    }
    println(find)
    val findLast = arrays.findLast {
        it > 2
    }
    println(findLast)
}

first & firstOrNull

集合中查找第一个 Lambda 返回 true 的元素,唯一区别就是 first 没有查找到会抛出异常, firstOrNull 会返回 null( firstOrNull 和 find 是等价的)。

fun main() {
    val arrays = arrayOf(1, 2, 3, 4)
    /**
     * 查找第一个元素大于 2 的元素,若没有抛出 NoSuchElementException 异常
     */
    val find = arrays.first {
        it > 2
    }
    /**
     * 查找第一个元素大于 2 的元素,若没有返回 null
     */
    val find2 = arrays.firstOrNull() {
        it > 2
    }
}

use

use 主要是对 Stream 的扩展, java 的读写文件相当费劲,尤其是复杂关流的操作,想想简直就是噩梦。有了 use 操作符就不需要关系那么多啦!

fun main() {
    /**
     * use 内部对流的关闭,做了处理,我们无需关系流是否关闭没
     */
    FileInputStream("build.gradle").use {
        String(it.readBytes())
    }.let(::println)
}

总结

实在太多了,大家边遇到边学习吧。其实原理都很简单,就是扩展封装罢了。最终要的就是,明白前面讲的函数为何能当参数传递。

这篇重在实践,高阶函数为我们开发带来了很多便利、大家多多去挖掘好用的高阶函数吧。

我个人认为这些函数能将很多复杂的业务变成链式写法。

推荐阅读

--END--

识别二维码,关注我们

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值