一、Lambda 表达式

1、基础语法

Lambda 表达式基础语法:

(parameters) -> expression
或 (parameters) ->{ statements; }

先理解:这段代码可理解为一个方法,小括号里的内容是方法入参,大括号里的内容是方法体。 而这行代码,就是一个 Lambda 表达式。所以 Lambda 表达式实际是一个方法(即函数)。

Java 8 中规定:Lambda 允许把函数(即Lambda 表达式)作为一个方法的参数(类似 JS 中的闭包)。 所以:Lambda 表达式是一个对象,而这个对象实际是一个方法。所以,Lambda 表达式是一个方法对象。

但是到底是什么对象呢?这个后续再细说。

2、语法简写形式

既然是一个方法,那么对自然有一些简写形式,如下:

  1. 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。 即()里面无需声明参数类型。()里面甚至可以什么都没有

  2. 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。 即()可以省略。

  3. 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。 即{}可以省略,同时语句后面的分号也可以省略。

  4. 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

就是说,小括号中的入参可省略,小括号可省略,大括号可省略,大括号中的内容还可省略。 注:小括号和小括号中的入参不能同时省略。怎么省略可详细参考:Java 8 Lambda 表达式 | 菜鸟教程

3、其他语法注意:

  1. lambda 表达式只能引用标记了 final 的外层局部变量。即不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。 注:修改final肯定会报错。另外,基本类型final就是final,引用类型final只表示变量地址(即引用)不可变,变量指向的内容还是实际可变的。

  2. 可以在 lambda 表达式中直接访问外层的局部变量: 注:final肯定可以被直接引用了。

  3. lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义) 注:这点应该由编译来保证。即在lambda 表达式内部使用的局部变量肯定为final,即使不显式声明。

  4. 在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。 注:这点肯定是的。同名肯定会出错。

二、方法引用和Lambda的关系

2.1 什么是方法引用?

  1. 方法引用是 lambda 表达式的一种特殊形式,即方法引用就是 Lambda 表达式(方法引用是 lambda 表达式的一种语法糖)。

  2. 方法引用用于获取一个已有方法的 Lambda 表达式形式。

上面两句应该说明了什么是方法引用。

2.2 方法引用的使用语法和限制

注:大写开头表示类名,小写开头表示对象。

  • 引用静态方法 ContainingClass::staticMethodName 例子: String::valueOf,对应的 Lambda:(s) -> String.valueOf (s) 比较容易理解,和静态方法调用相比,只是把.换为::

  • 引用特定对象的实例方法 containingObject::instanceMethodName 例子: x::toString,对应的 Lambda:() -> this.toString () 与引用静态方法相比,都换为实例的而已

  • 引用特定类型的任意对象的实例方法(不建议使用,比较麻烦) ContainingType::methodName 例子: String::toString,对应的 Lambda:(s) -> s.toString () 实例方法要通过对象来调用,方法引用对应 Lambda,Lambda 的第一个参数会成为调用实例方法的对象。

  • 引用构造函数 ClassName::new 例子: String::new,对应的 Lambda:() -> new String () 构造函数本质上是静态方法,只是方法名字比较特殊。

注意:第一和第三的区别在于::后面的方法是静态还是非静态,其他一致。

参考:Java 8 之方法引用 (Method References) - 永无止境,上下求索 - CSDN 博客

三、功能接口

3.1 功能接口定义

上面,一直说Lambda 表达式是一个对象,那是什么类型的对象呢? 这个类型就是功能接口类型。

在 Java 中,功能接口(Functional interface)指只有一个抽象方法的接口。 即如果一个接口只有一个抽象方法,Java 会自动认为该接口是功能接口。同时,该接口可以作为 Lambda 表达式的对象类型。 所以:Lambda 表达式是功能接口类型的对象,但这个功能接口类型不只一个,而是一类,这点要注意。

这里分析一下:Lambda 表达式既是方法(实现),又是对象。是什么方法(实现)?功能接口的方法(实现)。是什么类型接口的对象?功能接口类型的对象。 到这里,一切就清晰了。

那如何确定一个接口是不是功能接口呢?

  • 可以用@FunctionalInterface 注解标识。如果被标识的接口不符合功能接口规则,那么是会编译报错的。

3.2 JDK 中已有的功能接口

首先:这 4 个接口都是功能接口,所以其只有一个抽象方法。而这 4 个接口的不同在于抽象方法的参数和返回结果不同。理解了这点,就看也理解这四个接口了。

  1. Function.java 主要方法:R apply(T t); 功能说明: 将 Function 对象应用到输入的参数上,然后返回计算结果。

  2. Consumer.java 主要方法:void accept(T t); 功能说明: 该接口表示接受单个输入参数并且没有返回值的操作。

  3. Predicate.java 主要方法:boolean test(T t); 功能说明: 表示判断输入的对象是否符合某个条件。

  4. Supplier.java 主要方法:T get(); 功能说明: 无参数,返回一个结果。

总结一下上面的4个接口的区别:

接口 参数 返回结果
Function
Consumer
Predicate 布尔类型
Supplier

参考:JDK8 函数式接口 Function、Consumer、Predicate、Supplier - 酒肉猿 - CSDN 博客

四、使用实例:

参考:例子可参考:Java 8 Lambda 表达式详解 - 程序员干货 - SegmentFault 思否 到这里,你应该就知道可以怎么用了。

五、Stream API 与 Lambda 表达式

Stream API是JDK8的一个新特性,和 Lambda 的关系在于其可以接受 Lambda 表达式参数,使代码更加简洁方便。 具体使用可参考 JDK 文档:Java 8 中文版 - 在线 API 中文手册 - 码工具 中的Interface Stream<T>这里面有常用的map,sort等方法的接口声明。

至于 Stream 的更详细的知识,后续再写。暂时只写Lambda。

常用功能和方法说明:

六、参考:

  1. Lambda 表达式有何用处? - FACEBOOK THEM - CSDN 博客 注:特别优秀的一篇教程,很棒。

 

Java 8 Lambda 表达式详解的更多相关文章

  1. Java中lambda表达式详解

    原文地址:http://blog.laofu.online/2018/04/20/java-lambda/ 为什么使用lambda 在java中我们很容易将一个变量赋值,比如int a =0;int ...

  2. JAVA8之lambda表达式详解

    原文:http://blog.csdn.net/jinzhencs/article/details/50748202 lambda表达式详解 一.问题 1.什么是lambda表达式? 2.lambda ...

  3. Java8 Lambda表达式详解手册及实例

    先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下 ...

  4. Lambda表达式详解(例子详解)(转自:http://blog.csdn.net/damon316/article/details/51734661)

    Lambda表达式详解(例子详解)     lambda简介 lambda运算符:所有的lambda表达式都是用新的lambda运算符 " => ",可以叫他,“转到”或者 ...

  5. 类型:.net;问题:C#lambda表达式;结果:Lambda表达式详解

    Lambda表达式详解   前言 1.天真热,程序员活着不易,星期天,也要顶着火辣辣的太阳,总结这些东西. 2.夸夸lambda吧:简化了匿名委托的使用,让你让代码更加简洁,优雅.据说它是微软自c#1 ...

  6. Java lambda 表达式详解(JDK 8 新特性)

    什么是 lambda 表达式 lambda 表达式(拉姆达表达式)是 JAVA 8 中提供的一种新的特性,它使 Java 也能进行简单的"函数式编程". lambda 表达式的本质 ...

  7. java8 lambda 表达式详解

    lambada 表达式实质上是一个匿名方法,但该方法并非独立执行,而是用于实现由函数式接口定义的唯一抽象方法 使用 lambda 表达式时,会创建实现了函数式接口的一个匿名类实例 可以将 lambda ...

  8. Lambda表达式详解

    前言 1.天真热,程序员活着不易,星期天,也要顶着火辣辣的太阳,总结这些东西. 2.夸夸lambda吧:简化了匿名委托的使用,让你让代码更加简洁,优雅.据说它是微软自c#1.0后新增的最重要的功能之一 ...

  9. C# Lambda表达式详解,及Lambda表达式树的创建

    最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...

随机推荐

  1. 前端JS脚本将网页表格导出为Excel

    话不多说,上代码! <!DOCTYPE> <html> <head> <title>Excel Test</title> </head ...

  2. Android横竖屏布局总结

      Android横竖屏要解决的问题应该就两个:一.布局问题;二.重新载入问题. 1.布局问题:如果不想让软件在横竖屏之间切换,最简单的办法就是在项目的 AndroidManifest.xml中找到你 ...

  3. 每天进步一点点——Ganglia的Python扩展模块开发

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/39701245 注:本文涉及到的代码都在centos 6.5 64bit系统上通过验证,Gan ...

  4. 解决gremlin-dirver访问tinkerpop服务器提示序列化错误

    解决gremlin-dirver访问tinkerpop服务器提示序列化错误 问题描述 程序集成了gremlin-driver,访问远程tinkerpop服务器,在执行创建节点操作时,返回如下错误栈: ...

  5. RESTORE DATABASE命令还原SQLServer 数据库 bak

    今天在sqlServer20005 的management studio里使用bak文件还原数据库的时候,总是失败!Restore failed for Server 'ADANDELI'.  (Mi ...

  6. Nginx图片的防盗链配置

    [root@web01 www]# cat /app/server/nginx/conf/vhosts/default.conf server { listen default_server; ser ...

  7. The Way to Go读书笔记_第4章_基本结构和基本数据类型

    “_”标识符 _ 本身就是一个特殊的标识符,被称为空白标识符.它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用 ...

  8. poj Sudoku(数独) DFS

    Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13665   Accepted: 6767   Special ...

  9. binutils工具集之---objcopy,ranlib,size,strings,strip

    objcopy的作用是拷贝一个目标文件的内容到另一个目标文件中.objcopy使用GNU BFD库去读或写目标文件.objcopy可以使用不同于源目标文件的格式来写目的目标文件(也即是说可以将一种格式 ...

  10. windows包管理

    # windows包管理 ### 前言-----------------------------windows下好用的包管理程序类似于npm,安装curl程序方便.yum 的感觉 ### 包管理--- ...