Lambda介绍

Lambda,别名函数式编程,维基百科给出以下介绍:

函数式编程是一种编程范式。它把计算当成是数学函数的求值,从而避免改变状态和使用可变数据。它是一种声明式的编程范式,通过表达式和声明而不是语句来编程。

Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

λ 演算是数理逻辑中的一个形式系统,在函数抽象和应用的基础上,使用变量绑定和替换来表达计算。讨论 λ 演算离不开形式化的表达。在本文中,我们尽量集中在与编程相关的基本概念上,而不拘泥于数学上的形式化表示。λ 演算实际上是对前面提到的函数概念的简化,方便以系统的方式来研究函数。

Java中的Lambda

自Java8面世以后,也就代表着java从此以后同样支持lambda语法,使得之前繁琐的操作都可以使用简便的语法进行代替,最具代表性的改革就是新增的Stream类,让我们对一个集合的排序、过滤、映射和采集更加方便!

我们拟定一个场景,对于给定的一个int数组,过滤掉负数,并对剩余的元素进行排序,在java8之前我们的实现需要这么写:

int[] array = {7, -2, 3, 5, -9, 3, -5, -1, 6, 8, 20};

List list = new ArrayList();

//过滤负数

for(int i: array) {

if(i >= 0) list.add(i);

}

//排序

Collections.sort(list);

for(int i: list) {

System.out.println(i);

}

复制代码

使用Stream之后:

int[] array = {7, -2, 3, 5, -9, 3, -5, -1, 6, 8, 20};

Arrays.stream(array)

.filter(a -> a >= 0) //过滤

.sorted() //排序

.forEach(System.out::println);

复制代码

可以看到,实现的过程更加简洁和优雅,lambda大大节省了代码空间,提升了代码可读性,但使用的难度也随之提高,对于传统的编程方式,lambda语法无疑是一次重大的冲击。

Java中Lambda语法的使用

函数式接口

什么是函数式接口呢?在Java8之前,我们想实现一个接口,最简单的方式直接使用匿名类:

Comparator comparator = new Comparator() {

@Override

public int compare(Integer o1, Integer o2){

return o1 > o2 ? 1 : -1;

}

};

复制代码

这里要注意,Comparator是一个接口类型,它的内部只有一个需要被实现的方法,那么我们将之称之为函数式接口,一般的函数式接口都会加上@FunctionalInterface注解,如果该接口待实现的方法超出两个,你的IDE就会提醒你这不是一个规范的函数式接口,对于符合的,我们就可以使用lambda语法进行初始化:

Comparator comparator = (o1, o2) -> o1 > o2 ? 1 : -1;

复制代码

将之与java8之前的实现对比,我们发现有很多共同之处,我们来分析一下lambda的实现:

(o1, o2) -> o1 > o2 ? 1 : -1;

复制代码

将上部分以->做分割线,分成两部分,它们分别是(o1, o2)和o1 > o2 ? 1 : -1。很明显,前者代表着函数的两个入参,后者代表着两个入参的逻辑实现,由此可得,lambda由两部分组成:入参定义和逻辑实现。

对于一个函数式接口,我们可以用简单的lambda语法去实现接口内唯一的待实现方法,反推一下,对于lambda这种匿名的函数定义风格,如果一个接口存在两个待实现的方法,lambda则无法具体表示实现的是哪一个方法,由此反推可得,一个函数式接口最多只能有一个待实现方法。

JDK对Lambda的支持

通过函数式接口的定义和lambda实现我们知道了lambda语法的一个简单格式,但是在开发过程中,我们不可能对于每一个lambda的应用都定义个函数式接口,实际上,JDK中已经存在了很多lambda函数:

Function:接受一个参数输入,输入类型为 T,输出类型为 R。 抽象方法为R apply(T)。

BiFunction:接受两个参数输入, T 和 U 分别是两个参数的类型,R 是输出类型。抽象方法为R apply(T, U)。

Consumer:接受一个输入,没有输出。抽象方法为 void accept(T t)。

Predicate:接受一个输入,输出为 boolean 类型。抽象方法为 boolean test(T t)。

Supplier:没有输入,一个输出。抽象方法为 T get()。

BinaryOperator:接受两个类型相同的输入,输出的类型与输入相同,相当于 BiFunction。

UnaryOperator:接受一个输入,输出的类型与输入相同,相当于 Function。

BiPredicate:接受两个输入,输出为 boolean 类型。抽象方法为 boolean test(T t, U u)。

它们分别应用于不同的场景,以下将会有几个演示,首先使用lambda实现一个计算器:

BinaryOperator cal = (a, b) -> a + b;

System.out.println(bo.apply(1, 2)); // 3

复制代码

再来一个,使用lambda实现对数字正负的判断

int a = 1;

int b = -1;

Predicate predicate = i -> i >= 0;

System.out.println(predicate.test(a)); //true

System.out.println(predicate.test(b)); //false

复制代码

总结

在Stream中,lambda的应用非常广泛,我们如果想讲lambda更熟练的掌握,需要自己亲自的去使用lambda,在实战中去真正体会lambda的强大之处。

参考文章

java 匿名函数_Java8学习系列之匿名函数Lambda相关推荐

  1. python字典zip函数_Python学习系列之zip函数

    目录 一.zip函数(内建函数) 1.1 定义 Python 2:zip() 函数用于将可迭代的对象(字典,列表,元组,集合,字符串等)作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组 ...

  2. Java I/O系统学习系列二:输入和输出

    编程语言的I/O类库中常使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象."流"屏蔽了实际的I/O设备中处理数据的细节. 在这个系列的第一篇 ...

  3. sql中聚合函数和分组函数_学习SQL:聚合函数

    sql中聚合函数和分组函数 SQL has many cool features and aggregate functions are definitely one of these feature ...

  4. python imshow函数_opencv学习之显示图像-imshow函数

    序 上一篇opencv学习之读取图像-imread函数介绍完opencv读取图片函数imread,这次来介绍与它对应的图像显示函数imshow. imshow函数 imshow函数功能 imshow的 ...

  5. Java8学习系列之匿名函数Lambda

    Lambda介绍 Lambda,别名函数式编程,维基百科给出以下介绍: 函数式编程是一种编程范式.它把计算当成是数学函数的求值,从而避免改变状态和使用可变数据.它是一种声明式的编程范式,通过表达式和声 ...

  6. Java I/O系统学习系列一:File和RandomAccessFile

    I/O系统即输入/输出系统,对于一门程序语言来说,创建一个好的输入/输出系统并非易事.因为不仅存在各种I/O源端和想要与之通信的接收端(文件.控制台.网络链接等),而且还需要支持多种不同方式的通信(顺 ...

  7. Java 7 源码学习系列(一)——String

    String表示字符串,Java中所有字符串的字面值都是String类的实例,例如"ABC".字符串是常量,在定义之后不能被改变,字符串缓冲区支持可变的字符串.因为 String ...

  8. 学了java然后深入_JAVA8学习——从源码角度深入Stream流(学习过程)

    从源代码深入Stream / 学习的时候,官方文档是最重要的. 及其重要的内容我们不仅要知道stream用,要知道为什么这么用,还要知道底层是怎么去实现的. --个人注释:从此看出,虽然新的jdk版本 ...

  9. java 字符串常用函数_Java学习(5)——字符串常用函数

    不是我写的太麻烦了 转自: Java中的字符串也是一连串的字符.但是与许多其他的计算机语言将字符串作为字符数组处理不同,Java将字符串作为String类型对象来处理.将字符串作为内置的对象处理允许J ...

  10. Java I/O系统学习系列三:I/O流的典型使用方式

    尽管可以通过不同的方式组合IO流类,但我们可能也就只用到其中的几种组合.下面的例子可以作为典型的IO用法的基本参考.在这些示例中,异常处理都被简化为将异常传递给控制台,但是这只有在小型示例和工具中才适 ...

最新文章

  1. 计算机会计课程试题及答案,会计电算化课后简答题及答案.doc
  2. netflix 模式创新_创新设计模式:单例模式
  3. NYOJ-14 会场安排问题(经典贪心,区间完全不覆盖模板)
  4. 计算机单招语文试题,2019年高职单招语文模拟试题
  5. 微课|中学生可以这样学Python(例9.2):无界面通信录管理系统
  6. “不会MySQL,干啥都不行!”高级开发:工作、面试处处都会踩坑!
  7. python处理excel表格-60万行的Excel数据,Python轻松处理
  8. Oracle HA 之 SERVICE和DRM实战
  9. git 遇到fatal:multiple stage entries for merged file
  10. Newtonsoft.Json基础问题
  11. Halcon的一维码和二维码解码步骤和技巧
  12. 2019最新超详细HUSTOJ在线判题系统及Virtual Judge的搭建
  13. logo语言是计算机语言吗,LOGO语言的编程
  14. win10关闭windows聚焦_关于Windows 10 Windows聚焦功能失效
  15. 一键激活Win8.1、wni7\winser(无需联网)
  16. 安全系列之一——SYS-VUL-0048漏洞
  17. android自动修音,唱吧自动一键修音软件-唱吧自动修音app8.8.6 安卓手机版-东坡下载...
  18. VSTO之PPT幻灯片放映时间记录
  19. 微软研究院科大实习生聚餐
  20. ESRI中国(北京)招聘售前技术工程师(招聘结束,谢谢大家!)

热门文章

  1. home目录权限linux,linux 文件/文件夹权限
  2. Linux系统管理干货总结笔记
  3. sap是mysql数据库_sap系统用什么数据库
  4. 麦客表单无法登录打开显示空白怎么办?
  5. pycharm更改运行环境
  6. html仿写网易云音乐人页面,vue模仿网易云音乐的单页面应用
  7. HibernateDaoSupport和nbsp;Hiber…
  8. Win7系统网络适配器不见了的解决办法
  9. 携程网机票查询token参数的生成过程
  10. TMI 202106论文汇总(IEEE Transactions on Medical Imaging)