Kotlin的高阶函数和常用高阶函数

文章来源:企鹅号 - Android先生

高阶函数的定义

将函数当做参数或者是返回值的函数

什么是高阶函数

可以看看我们常用的 函数:

首先我们可以知道, 是 的扩展函数,然后参数是 ,但是 不再像和我们以前Java那样传递的是一个对象,这时传递的是一个函数。这个函数的入参为 ,返回值为 。所以 也是一个高阶函数,因为它将函数当做参数进行传递了。我们尝试着去调用一下 函数:

调用的时候,我们将 函数传递给了 函数,这里采用的是函数引用。就上诉代码,我们还可以结合 表达式来进行处理:

其实以上几种的方式得到的结果都是一样的,但是第一种就是简洁了许多。

我们再定义一个类,用来打印 的值:

根据函数引用的特性,我们可以这样调用 函数:。由于 中的 函数的入参类型是 类型,也就是任意类型,不管 传递的是什么值都可以接收。那现在我们再将其作为 的参数传递进去:

编译器告诉我们这个是错误的。那我们来分析一下吧:我们再定义一个 类

然后进行以下操作:

可以看到 分别对 和 的解释:

是一个方法,然后参数类型为 ,返回值为

也是一个方法,但是参数有两个,分别是 和 类型, 返回值为

在 中,只有一个参数传递,但是 需要的是两个参数,肯定就会报错,所以我们需要对此进行修改:

这个样子就OK了。

常用高阶函数

map:变换

通常我们会使用以下的方式来实现对集合中的元素进行修改的操作:

如果采用这种方式,远远不能体现Kotlin的优势了,这个和Java有什么区别呢?「狗子,上map」:

从打印结果可以看到他们的实现效果是一模一样的,这个就是 的功能,可以对集合中的元素进行你想要的操作,是不是跟 的 很类似呢!我们来细看一下 的实现原理:

方法中主要做的就是调用 方法,然后传递的是新创建并且初始长度为10的 和 函数,在 方法中,对集合进行迭代,然后将进行变换后的数据添加到新的集合中,最后返回新的集合。

操作不仅可以将元素变换成与之前类型相同的元素,也可以变化成与之前元素类型不同的元素,具体你想变换成什么类型,这个是不做限制的。

flatMap:变换

看起来跟 很相似,其实真的很类似,搞得有时候自己都不知道应该使用哪个操作符了,那就从源码来看看它们之间的区别吧。

可以看到 中的参数 是一个返回值为 的函数,而 的参数 是一个返回值为 的函数。然后调用 方法,将 和一个新创建的 传递给了 方法。在 方法中,对当前的集合进行了迭代,然后将执行过变换操作后的集合数据全部添加到新的集合中,最终返回新的集合。

和 的主要区别就是在于传入的函数的返回值,一个是任意对象,一个是实现了 接口的对象

reduce

例子:打印集合中的元素之和

还是直接对源码进行分析吧,感觉看了源码就一目了然了。

首先对当前的集合进行判空处理,接着将第一个元素赋值给 , 的类型是 。然后对当前集合进行迭代处理,并调用我们传递进去的参数 , 函数中传递了两个参数,一个是 类型的,一个是集合元素类型的。 函数的返回值也是 类型的,将 的返回值重新赋值给 。迭代完毕以后返回我们的 。

其实通过我们解读源码以后,我们就可以知道 函数会将上一次的计算结果传递到下一次计算中,我们可以利用这个方式来实现以下字符串拼接,当然我们的字符串拼接有其他更好的方式,这里只是做为讲解 的例子而已:

fold:能够添加初始值的reduce

不得不说, 跟 的作用基本是一致的,只是 能够添加初始值,什么叫做能够添加初始值呢?让我们来举个栗子看看呗!

还是看源码吧:

看着源码就会觉得这些函数的操作很是简单了。 函数还有很多的兄弟:

说的再多也不如看结果

这个函数就是多了一个 的参数,具体的用处暂时没有发现,就不做数据打印了。

filter:过滤

例子:过滤集合中的奇数

上源码:

在 中创建新的集合 ,将 和 函数一并传递给 函数。在 函数中,先对当前的集合进行遍历,如果满足条件 就将当前的元素添加到新的集合中, 就是我们传递进来的那个函数,返回值是一个 类型的。

takeWhile:截取集合中的数据,直到第一个不满足条件的元素为止

例子:截取集合中不能够被5整除的数,直到第一个不满足条件的元素为止。

源码:

let:将调用者当做参数传递给指定的函数

例子:省略if空判断

源码:

源码也是很简单,就是将调用者传递给传入进来的函数并执行传入进来的函数。

apply:执行指定函数,并且返回调用者

例子:修改person类的age属性

上诉的例子真的只是例子,它没有跟你讲 有多强大,它只是描述了的作用。源码:

就是单纯的执行函数 并返回调用者。

with

例子:文件读取

源码:

接收两个参数,一个是 ,上诉例子中就是 ,另一个就是 ,在上诉例子中,我们使用了 表达式,所以这个函数就移到了括号外面了。

疑惑点

函数定义中 `T.() -> Unit` 和 `() -> Unit` 的区别

我们一般定义函数都会选择定义

上诉代码表示: 的扩展方法 接收一个 的函数,该函数是无参无返回的。

那我们再见识见识 这种方式定义的方法,其实也很多见了:

可以看到 函数使用的是 这种方式,他们两到底有啥区别呢?

我在 定义了两个方法:

分别使用 调用这两个方法试试:

从图片中可以看出 : 中的 对象指的是调用对象 ,也就是 ,而 没有提示,那么我们就看打印吧:

原来 方法中的 对象指的是外部对象,在这里就是我们的 对象。

总结

这两个函数唯一的区别就是 与 的区别,我们调用时,在代码块里面写this,的时候,根据代码提示,我们可以看到,连个this代表的含义不一样, 里的this代表的是自身实例,而 里,this代表的是外部类的实例

感谢

[Kotlin中,函数作为参数,T.()->Unit 和 ()->Unit 的区别][https://www.jianshu.com/p/88a656e59c61]

This is All

Kotlin的高阶函数和常用高阶函数的更多相关文章

  1. 生成器的send方法、递推函数、匿名函数及常用内置函数

    生成器的send方法 在使用yield方法创建生成器时,不仅可以使用next方法进行取值,还可以通过send方法向生成器的内部传值 什么是send方法? send方法相当于高级的next方法,send ...

  2. Kotlin——高级篇(二):高阶函数详解与标准的高阶函数使用

    在上面一个章节中,详细的讲解了Kotlin中关于Lambda表达式的语法以及运用,如果还您对其还不甚理解,请参见Kotlin--高级篇(一):Lambda表达式详解.在这篇文章中,多次提到了Kotli ...

  3. python内置常用高阶函数(列出了5个常用的)

    原文使用的是python2,现修改为python3,全部都实际输出过,可以运行. 引用自:http://www.cnblogs.com/duyaya/p/8562898.html https://bl ...

  4. 【重温基础】JS中的常用高阶函数介绍

    Ps. 晚上加班到快十点,回来赶紧整理整理这篇文章,今天老大给我推荐了一篇文章,我从写技术博客中收获到了什么?- J_Knight_,感受也是很多,自己也需要慢慢养成记录博客的习惯,即使起步艰难,难以 ...

  5. 5. vue常用高阶函数及综合案例

    一. 常用的数组的高阶函数 假设, 现在有一个数组, 我们要对数组做如下一些列操作 1. 找出小于100的数字: 2. 将小于100的数字, 全部乘以2: 3. 在2的基础上, 对所有数求和: 通常我 ...

  6. 函数和常用模块【day04】:高阶函数(七)

    本节内容 1.介绍 2.具体实用 3.eval()函数 一.介绍 高阶函数:变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数. 二.具体实用 其实说白了,高阶函数功能就 ...

  7. Python 基础之匿名函数 迭代器和高阶函数

    一.匿名函数 lambda表达式 用一句话来表达只有返回值的函数,叫匿名函数特点:简洁方便语法:lambda 参数: 返回值 1.不带有参数的lambda表达式 def func():    retu ...

  8. python函数基础:嵌套函数、作用域、匿名函数、高阶函数、递归函数

    嵌套函数: 1. 函数内部可以再定义函数 2. 函数只有被调用之后才会执行 看如下代码: age = 18 def func1(): age = 22 print(age) def func2(): ...

  9. 高阶函数HOF和高阶组件HOC(Higher Order Func/Comp)

    一.什么是高阶函数(组件),作用是什么? 子类使用父类的方法可以通过继承的方式实现,那无关联组件通信(redux).父类使用子类方法(反向继承)呢 为了解决类(函数)功能交叉/功能复用等问题,通过传入 ...

随机推荐

  1. SpringDataJpa实体类常用注解

    最近公司在使用SpringDataJpa时,需要创建实体类,通过实体类来创建数据库表结构,生成数据库表. 下面我们就来看下在创建实体类时一些常用的注解吧!!! 1.实体类常用注解 @Entity 标识 ...

  2. U盘重装系统

    一.准备工作 (1)8G以上空间的U盘一个: (2)将U盘制作好启动工具: 1.下载启动工具制作软件(常用的有:大白菜.电脑店.老毛桃.快启动等等一系列软件,直接百度这些软件的名称,或者百度U盘启动制 ...

  3. 【Activiti】crm与工作流的整合,一个完整的流程实例创建到任务完成的过程

    1.建立任务列表页面--根据用户的nickName作为assignee查询其所拥有的任务列表 2.在任务后添加办理按钮 3.点击办理按钮,出现流程办理框,其中详细显示了该任务的相关详细信息,本实例中为 ...

  4. PHP高级进阶之路

    一:常见模式与框架 学习PHP技术体系,设计模式,流行的框架 常见的设计模式,编码必备 Laravel.ThinkPHP开发必不可少的最新框架 YII.Symfony4.1核心源码剖析 二:微服务架构 ...

  5. Python新式类与经典类(旧式类)的区别

    看写poc的时候看到的,思考了半天,现在解决了 转载自http://blog.csdn.net/zimou5581/article/details/53053775 Python中类分两种:旧式类和新 ...

  6. Nginx请求限制配置

    Nginx请求限制配置 请求限制可以通过两种方式来配置,分别是  连接频率限制和请求频率限制 首先我们要知道什么是http请求和连接,浏览器和服务端首先通过三次握手完成连接,然后发起请求,传输请求参数 ...

  7. String,到底创建了多少个对象?

      String str=new String("aaa"); <span style="font-size:14px;">String str=n ...

  8. 第十篇.5、python并发编程之协程

    一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...

  9. 图书管理系统UML建模

    图书管理系统UML建模 用例图 借阅者请求服务用例图 图书管理员处理借书还书用例图 系统管理员系统维护用例图 时序图 系统管理员添加书籍时序图 协作图 借阅者预留书籍协作图 状态图 书的状态图 活动图 ...

  10. 动画学习之Music图形绘制

    今天来实现一个类似于网易云音乐类似的动态效果,在用网易云音乐听歌时会有一个类似这样的效果,如下: 而咱们这次要实现的效果如下: music图形的绘制: 在实现动画之前先来将静态的图形绘制出来, 如下: ...