java lambda 高阶函数_一文弄懂 kotlin lambda与高阶函数

阅读本文能解决什么问题

我发现很多学过kotlin的人,迟迟不敢在项目中运用,主要是因为kotlin的 lambda与高阶函数没有学好。这2个东西往往是一起运用的。 网上很多类似的文章都讲的不够通透,导致大部分人都卡在这里。或者有一些人即使写了kotlin 但是也没用好lambda与高阶函数,导致kotlin的代码 全是java的味道。

大家可以用一下新版本的android studio,然后新建一个kotlin语言的loginActivity,如果里面的代码你能无障碍的基本看懂,那这篇文章就不用再看了,如果看起来障碍很大,那么建议你仔细看完这篇文章,之后再返回去看这个loginActivity的代码,相信结果是完全不一样的。

最后总结一下我的观点:想写好Kotlin的代码就看你对lambda与高阶函数理解的有多深,早期纠结那些晦涩的语法糖没有任何意义。

到底啥是匿名函数

085a9a913bee062c59892bfbb6625f73.png

那这个func 又怎么理解呢?他为啥可以接受一个函数作为参数?

e49de34fe95c930ed3edd29bb7b297e1.png

3bcdc4763e7910edce3cf638ec1c2890.png

这里有人会问了,你咋知道 这个匿名函数是没有返回值的啊?

因为lambda表达式有一个特点,lambda括号里面的函数最后一行就是这个函数的返回值, 图中我们最后一行

是个print语句,这个print函数显然是没有返回值的,所以这个lambda 也就是这个匿名函数也就没有了返回值了。

带参数的lambda

2ec25ead77455564f11da452b7979de3.png

然后我们反编译看一下这段代码

94129c22b53a5bd4174f45fa1887d410.png

我们换个写法

11e6a1e5684fc72229212a72a1ab577d.png

我们再看一下反编译的:

563c315706001e923d76ee33c3b2240e.png

下面我们再改进一下写法:

563d9c2e5e27ccf97a1f39b014cb5a9d.png

那当然还有终极的简写,也就是平常我们使用最多的写法:

f077ef967187eb45b3e06e996b411241.png

很多人学不好lambda就是因为上来就看这个最简单的写法,而不知道这种写法是怎么来的。你搞清楚

这种写法的进化原因,自然就真正理解了lambda了。

ac3f3a39aedc9b882adcb17213064bbc.png

来个更进一步 2个参数的

95dedb9be6873dcc38f5a65405d39be8.png

看下执行结果

cb2783109633b48994d66090a461aa37.png

4ea26900bdd5a8cbbde0ef235fc3df9a.png

2e2ffc043b615fe922530113fc7fac32.png

实际上kotlin中的lambda 就是一个匿名函数,java8的lambda表达式 却是一个sam的语法糖

高阶函数

有了前面lambda 的铺垫,高阶函数 的理解就不难了。 下面给高阶函数下一个定义:

参数类型包含函数类型,或者返回值类型是一个函数类型 的函数 都可以称之为是高阶函数。

来看几个简单的高阶函数的例子:

659e848d3d5b84a94f833b8f02e8cc2e.png

看下源码:

edbc8d397cd539960b06f9d1bf3c37dd.png

再看个函数

0ef2f203e60684e30c4c5a3a88d89982.png

然后我们看一下map函数的定义

a8e747e742c5180cd0d03d6f394a6b34.png

所以你看高阶函数 也没什么难的,主要你能理解lambda 那么你就能理解好高阶函数

谷歌源码里最常用的几个高阶函数

无非就是let run also apply use 这么5个,网上关于这几个函数的资料很多,但是介绍的我觉得都相当一般,这里我重新介绍一下 这几个函数对应的使用场景。 掌握了他们,可以说 理解kotlin的代码 就不会存在什么障碍了。

这里要着重说明的是,其实run函数和apply函数 并没啥大作用。平时自己写 主要还是let also 和use

看一段代码,看看let和also的区别

a2870874153d5ccc07b50dfe65ad9f01.png

最后一个use操作符,是个人最爱的一个操作符,因为这东西真的省事。我演示一遍你就知道他有多省事了!

66f3f46891084ddbf4db3a4a79391e8b.png

最后用一张图来总结:3ef45c2f12505f5da5a2bd89c3727a44.png

高阶函数-集合的变换

我们平时开发业务代码时 其实最主要的工作就是对一个集合进行增删改查,过滤啊 之类的操作。

kotlin中 提供了大量对集合操作的 高阶函数,理解好他们 对你读代码或者是写代码的操作都是非常非常有帮助的。

前面的代码中我们已经演示过了for each循环的用法 这里补充一点,foreach函数是可以提前跳出的。

0af235e4a557a7ef69100ecddc2c99b7.png

当然上面的写法一般是不推荐的,因为确实很迷惑人。 有更高级的函数 可以满足你对集合的要求。

看下图:767c9fdf977e22e65d6eed6e2e1bf239.png

看个例子:2e8a1998fb7eaab35e26886f4d655e06.png

有时候我们对一个集合的操作,可能不止一个函数,需要多个函数协同操作,这个时候有更方便的

写法。

b9dc3f7d5250a77cf0225b1616d0b43b.png

有人要问了,这个asSeq不调用 是啥效果?我们可以看一下

a1c0a247ffe98903c2e6bd73cbac45ab.png

ee2608bfd7f00c027e3916851f73c222.png

再看一个例子

94e221e8fc7d462213b96121859672a0.png

看下flatmape9b6c0dc7969a1ea29cf001e370d189f.png

集合的聚合操作

先看一张图 了解一下主要的聚合操作8d51309158fda5d6ba2bcd9baf872e17.png

看下fold的使用5b936b5d515d5982c6c482d52ffdd310.png

b5484ce0ca309bf2c90b6dd3f63951b4.png

其余的2个高阶函数就不再演示了。大家用到的时候自行查阅api即可。

试试高阶函数和lambda 怎么组合使用 解决问题?

前面已经学完了lambda和大部分高阶函数,这里我们组合一下他们的用法,重新将知识串起来。

1.统计一个文件里 除了空格字符以外,每个字符出现的次数(尽量只使用lambda)

/**

* 1.读文件 然后把文件的内容 转成char的数组

* 2.过滤数组,空格符直接忽略

* 3.用groupBy 来将整个数组 重新分组(分组的结果是一个map), key就是出现的字符,value就是出现的全部字符

* 4.用map操作符 再将这个map 拍平成一个list,这个list的 内容形如:e 出现次数: 21

* 5.用let操作符 将结果打印出来即可

*/

fun main() {

File("/Users/wuyue/IdeaProjects/KotlinTest/src/enumTest.kt").readText().toCharArray().filterNot {

it.isWhitespace()

}.groupBy {

it

}.map {

it.key + " 出现次数: " + it.value.size

}.let {

println(it)

}

}

复制代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值