今天开始后续的几篇Kotlin的文章会介绍Kotlin中Lambda表达式相关的内容。

什么是Lambda表达式

在Java8中引入了Lambda表达式,这是最令Java开发者激动和期待的一个功能。那究竟什么是Lambda表达式呢?

Lambda表达式本质上是可以传递给其他函数的一小段代码,我们在之前的Java或者Kotlin中,一个函数的参数可以是一种简单的基本数据类型变量或一个对象实例变量。Lambda表达式的出现可以让我们可以把一段代码当做一个值来进行对待,由于是值,便可以进行传递,所以Lambda可以被当做参数传递给其他函数。Lambda表达式的出现,让我们的代码更加简洁。

Kotlin中的Lambda表达式

上面的文字描述可能比较抽象,我们举一个实际的例子。我们定义一个数据类人(对于Kotlin数据类不了解的可以查看这篇文章Kotlin系列之数据类和类委托)。我们的目的是找出一堆人中年龄最大的那个人。

我们先用最基础的Kotlin知识来解决上述问题。代码示例如下:

data class People(val name: String, val age: Int)fun findTheOldest(peopleList: List<People>) {var maxAge = 0var theOldestPeople: People? = nullfor (people in peopleList) {if (people.age > maxAge) {maxAge = people.agetheOldestPeople = people}}println(theOldestPeople)
}fun main(args: Array<String>) {val peopleList = listOf<People>(People("小白", 22),People("小红", 23), People("琦琦", 20))findTheOldest(peopleList)
}
复制代码

但是Kotlin中可以使用库函数配合Lambda将代码进行大大的简化,我们先看看可以最终可以简化到何种程度。代码如下:

fun main(args: Array<String>) {val peopleList = listOf<People>(People("小白", 22),People("小红", 23), People("琦琦", 20))//关键代码就这一行println(peopleList.maxBy { it.age })
}
复制代码

是不是被惊艳到了,代码量大大大大减少了,而且代码所表达的功能也更加清楚了。下面我们就来看看上面的那么多代码是怎么利用Lambda表达式变成一行代码的。

Lambda表达式的简化过程

下面就来看看具体的演变过程。 首先maxBy这个函数式类似于一个比较器,它不关心具体的集合中的元素是什么类型,只需要我们传入比较的规则即可,我们上面比较的规则是人们的年龄。所以我们可以把比较规则使用Lambda来书写传入maxBy函数中。

首先先让我们看看Lambda表达式的语法。一个Lambda表达式的基本结构是这样:

{参数1: 类型, 参数2: 类型, [...] -> 函数体}
复制代码

可以看出,一个Lambda表达式被一个花括号包围,参数并没有是哟圆括号括起来,参数列表和函数体之间使用箭头进行分隔。

所以我们依据上面的格式要求,会写出下面这样的代码:

peopleList.maxBy({p: People -> p.age})
复制代码

上面是最原始的Lambda表达式代码。

根据Kotlin的语法约定: 如果Lambda表达式是函数调用的最后一个实参,它可以放在括号的外面。 由于在这个例子中Lambda表达式是maxBy函数的唯一实参,也自然是最后一个实参,所以代码就变成下面这样。

peopleList.maxBy(){p: People -> p.age}
复制代码

但是要记住,当函数有多个实参时,我们既可以将Lambda表达式留在括号内,也可以放在括号的外面,但当我们传递的是两个或更多个Lambda表达式时,不能把超过一个的Lambda表达式放在括号外面。

根据Kotlin的语法约定: 如果Lambda表达式是函数的唯一实参,可以去掉空的圆括号对。 所以上面的代码又会进一步变为下面这样。

peopleList.maxBy{p: People -> p.age}
复制代码

根据Kotlin的语法约定: 如果Lambda表达式中参数的类型可以被推导出来,那么类型声明可以被省略。 这个例子中编译器知道maxBy要处理的每一个元素都是People类型,所以这里不需要显式指定类型。 所以代码被进一步简化为下面这样。

peopleList.maxBy{p -> p.age}
复制代码

当然我们前面也说了,Lambda就是一段代码,我们可以使用变量存储它,便于多次使用。当我们使用变量存储Lambda表达式时,由于缺少上下文环境,所以无法进行参数类型推断,所以必须显式指定参数类型。

根据Kotlin的语法约定: 如果Lambda表达式中只有一个参数,并且这个参数的类型可以被推断出来,那么可以使用默认参数名称it来代替命名参数。 所以最终代码变成了这样。

peopleList.maxBy{it.age}
复制代码

it虽然可缩短代码,但是却不可以滥用,在Lambda表达式嵌套的情况下,it没法清楚表示到底引用的是哪个值,会造成代码的混乱,所以在这种情况下建议显式指定参数名称。

最后再补充一个小点,Lambda表达式并没有限定是单个表达式,他截图包含更多的语句,当包含更多的语句时,最后一个表达式就是Lambda表达式的结果,就像下面这样:

fun main(args: Array<String>) {val sum = {x: Int, y: Int ->println("start to calc...")x + y}println(sum(1, 2))
}
复制代码

写在最后

通过上面的介绍,是不是已经被Kotlin中的Lambda表达式吸引了呢,后续还有几篇文章将介绍Kotlin中Lambda表达式的更多内容。

欢迎关注我的微信公众号,不定期更新Kotlin相关内容。

Kotlin系列之Lambda表达式(1)相关推荐

  1. Kotlin系列之Lambda编译成字节码过程完全解析

    简述: 今天带来的是Kotlin浅谈系列第七弹,上篇博客我们聊到关于Kotlin中的lambda表达式的一些语法规则和基本使用.然而我们并没有聊到Kotlin的lambda表达式的本质是什么?我们都知 ...

  2. JDK8系列之Lambda表达式教程和示例

    JDK8系列之Lambda表达式教程和示例 1.Lambada 表达式简介 Lambda 表达式是一种匿名函数,但对Java中的Lambda表达式而已并不完全正确,简单来说,Lambda表达式是一种没 ...

  3. 【Kotlin】Kotlin 中使用 Lambda 表达式替代对象表达式原理分析 ( 尾随 Lambda - Trailing Lambda 语法 | 接口对象表达式 = 接口#函数类型对象 )

    文章目录 一.尾随 Lambda - Trailing Lambda 语法 二.Kotlin 中使用 Lambda 表达式替代对象表达式原理 1.Lambda 替换对象表达式 2.原理分析 3.示例分 ...

  4. kotlin学习笔记——lambda表达式

    先简单说说lambda表达式: (Type a, Type b, ...) -> {...} 左边是参数(参数类型可省略),如果只有一个参数括号也可以省略,右边是函数体和返回结果(大括号可省略) ...

  5. 用c#算成绩的总和_C# 基础知识系列- 6 Lambda表达式和Linq简单介绍

    前言 C#的lambda和Linq可以说是一大亮点,C#的Lambda无处不在,Linq在数据查询上也有着举足轻重的地位. 那么什么是Linq呢,Linq是 Language Intergrated ...

  6. Java 8系列之Lambda表达式

    概述 使用Lambda表达式也有一段时间了,有时候用的云里雾里的,是该深入学习Java 8新特性的时候了.作为Java最大改变之一的Lambda表达式,其是Stream的使用基础,那就以它开始吧. 这 ...

  7. .NET笔记系列:LAMBDA表达式常用写法

    这里主要是将数据库中的常用操作用LAMBDA表达式重新表示了下,用法不多,但相对较常用,等有时间了还会扩展,并将查询语句及LINQ到时也一并重新整理下: 1.select语句:books.Select ...

  8. 学习Kotlin(五)函数与Lambda表达式

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  9. Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)

    作者:Antonio Leiva 时间:Jan 5, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin/ 由于Lambda表达式允许更简单的方式建模式 ...

最新文章

  1. 在不使用notifyDataSetChanged()方法,怎样选中Item中的内容
  2. 设计模式笔记 10.Facade 外观模式(结构型模式)
  3. 【转】深入剖析iLBC的丢包补偿技术(PLC)
  4. arcgis使用工具箱导出dbf_ArcGIS——好好的属性表,咋就乱码了呢?
  5. 那些对你说学历不重要,技术重要的人,他们大部分都是有学历的。
  6. zabbix监控工具
  7. 挖矿区块链_使用Java语言从零开始创建区块链
  8. linux时间树,linux小知识之查看系统时间
  9. linux 挂载windows共享目录 is not a valid block device
  10. 西北农林科技大学c语言上机题题答案,西北农林科技大学C语言上机实习4答案
  11. 各种电信安卓手机玩机宝典!——转自天翼圈in189
  12. python爬虫抓取链家租房数据
  13. 计算机打字在哪点,电脑打字在哪里打开
  14. anaconda 安装 TensorFlow 过程记录
  15. C++动态开辟数组空间
  16. i5 13490f参数 怎么样 i5 13490f功耗 酷睿i513490f什么水平级别
  17. 朴素贝叶斯模型、SVM模型笔记
  18. [附源码]计算机毕业设计JAVA小说网站的设计与实现1
  19. LyX 发布撑持 CJK 的 1.5 正式版
  20. RedHatLinux6.5下安装无线网卡驱动

热门文章

  1. 图像的通道(channels)问题
  2. Python以进程方式无黑窗在后台运行(无命令窗)
  3. Python三目运算符
  4. Linux下编译运行Go程序
  5. python 高阶函数一 概念
  6. mysql服务器设置其他电脑访问
  7. Google Chrome 浏览器插件开发学习
  8. 第一章 软件工程概论
  9. ZZ:WSS 扩展文件夹的属性--如何给文件夹添加扩展字段 from Jianyi0115
  10. 关于“数据中心”的最强入门科普