Java 8新特性----Lambda
Lambda
一、如何辨别Lambda表达式
Runnable noArguments = () -> System.out.println("Hello World");
ActionListener oneArgument = event -> System.out.println("button clicked");
Runnable multiStatement = () -> {
System.out.print("Hello");
System.out.println(" World");
};
BinaryOperator<Long> add = (x, y) -> x + y;
BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;
1)没有参数用空“()”表示。
2)只有一个参数,括号可以省略,只写参数名。
3)Lambda 表达式的主体不仅可以是一个表达式, 而且也可以是一段代码块, 使用大括号
( {}) 将代码块括起来。 该代码块和普通方法遵循的规则别无二致,可以用返
回或抛出异常来退出。 只有一行代码的 Lambda 表达式也可使用大括号, 用以明确 Lambda
表达式从何处开始、 到哪里结束。
4)Lambda 表达式也可以表示包含多个参数的方法。 这时就有必要思考怎样去阅
读该 Lambda 表达式。 这行代码并不是将两个数字相加, 而是创建了一个函数, 用来计算
两个数字相加的结果。 变量 add 的类型是 BinaryOperator<Long>, 它不是两个数字的和,
而是将两个数字相加的那行代码。括号中的参数就可以有注解和final。
5)到目前为止, 所有 Lambda 表达式中的参数类型都是由编译器推断得出的。 这当然不错,
但有时最好也可以显式声明参数类型, 此时就需要使用小括号将参数括起来, 多个参数的
情况也是如此。
6)方法/构造器引用:Lambda表达式调用参数的一种简便写法。
三种写法:
对象::实例方法
类::静态方法
类::实例方法
第三种情况,第一个参数会成为执行方法的对象
this::实例方法
super::实例方法
闭合类.this:方法
如:
artist -> artist.getName() //可以写成 Artist :: getName
button.setOnAction(event -> System.out.println(event)); //可以写成 button.setOnAction(System.out::println());
构造函数有同样的写法:
(name, nationality)-> new Artist(name, nationlity) //可以写为 Artist :: new
也可以有数组构造器引用:
int[]::new //等同于x -> new int[x]
7)目标类型是指 Lambda 表达式所在上下文环境的类型。 比如, 将 Lambda 表
达式赋值给一个局部变量, 或传递给一个方法作为参数, 局部变量或方法参
数的类型就是 Lambda 表达式的目标类型。
二、引用值,而不是变量
匿名内部类需要引用它所在方法里的变量时(局部变量),需要将变量声明为final。
Java 8中放松了这一限制,可以引用非final变量,但该变量在既成事实上必须是final(只能给该变量赋值一次,
如果试图给该变量多次赋值,然后在Lambda表达式中引用它,编译器就会报错)。
这种行为也解释了为什么lamdba表达式为闭包-------含有自由变量(不是传入参数,且没有在方法块中定义的变量)的代码块。
变量的值:除了基础类型外,变量的值指的是它的引用(地址)。 例如:
String msg = "hello world"; msg = "good morning"; executor.submit(()->System.out.println(msg));
这么做的原因与匿名内部类类似。
三、函数接口
函数接口是只有一个抽象方法的接口,用作lambda表达式的类型。

四、类型推断
可省略Lambda表达式中所有参数的类型。
无法推断出类型的报错信息:
Operator '& #x002B;' cannot be applied to java.lang.Object, java.lang.Object.
五、重载和继承
1.重载
1)Lambda 表达式作为参数时,其类型由它的目标类型推导得出, 推导过程遵循
如下规则:
1.如果只有一个可能的目标类型, 由相应函数接口里的参数类型推导得出;
2.如果有多个可能的目标类型, 由最具体的类型推导得出;
3.如果有多个可能的目标类型且最具体的类型不明确, 则需人为指定类型。
2)每个用作函数接口的接口都应该添加@FunctionalInterface注释,该注释会检查被注释接口是否符合函数接口的标准。
2.继承
1)默认方法
引入默认方法目的:接口的向后兼容(如果没有默认方法,我们在接口中定义一个新方法时......)。
1.无论函数接口,还是非函数接口都可以使用默认方法。
2.任何时候,默认方法与类中的方法产生冲突,优先选择类中的方法。
3.多重继承,类实现的多个接口中有方法签名相同的默认方法,此时编译器会报错:
class Musical Carriage inherits unrelated defaults for rock() from types Carriage and Jukebox。
解决方法:重写:
public class MusicalCarriage
implements Carriage, Jukebox {
@Override
public String rock() {
return Carriage.super.rock();
}
}
六、与抽象类的区别
接口和抽象类之间还是存在明显的区别。 接口允许多重继承, 却没有成员变量; 抽象类可
以继承成员变量, 却不能多重继承。
七、接口的静态方法
在Java8中你可以为接口添加静态方法。
如果一个方法有充分的语义原因和某个概念相关, 那么就应该将该方法和相关的类
或接口放在一起, 而不是放到另一个工具类中。 这有助于更好地组织代码, 阅读代码的人
也更容易找到相关方法。
Java 8新特性----Lambda的更多相关文章
- Java 8 新特性 - Lambda表达式
Lambda表达式 vs 匿名类既然lambda表达式即将正式取代Java代码中的匿名内部类,那么有必要对二者做一个比较分析.一个关键的不同点就是关键字 this.匿名类的 this 关键字指向匿名类 ...
- 浅析Java 8新特性Lambda Expression
什么是Lambda Expression 对于Lambda Expression,我的理解是,它是一个函数表达式,如下: (int x, int y) -> x - y 符号左边定义了函数的输入 ...
- Java 8新特性--Lambda表达式作为返回值
lambda表达式作为方法的返回值:
- Java 8 新特性--Lambda表达式作为方法参数
Lambda表达式的使用场景: 当方法的参数是一个函数式接口时,可以使用Lambda表达式进行简化—— 首先,前提是Runnable接口是一个函数式接口,经过查看源码得知,确实如此: 将Runnabl ...
- Java 12 新特性介绍,快来补一补
Java 12 早在 2019 年 3 月 19 日发布,它不是一个长久支持(LTS)版本.在这之前我们已经介绍过其他版本的新特性,如果需要可以点击下面的链接进行阅读. Java 11 新特性介绍 J ...
- Java 8 新特性:Lambda、Stream和日期处理
1. Lambda 简介 Lambda表达式(Lambda Expression)是匿名函数,Lambda表达式基于数学中的λ演算得名,对应于其中的Lambda抽象(Lambda Abstract ...
- Spring 4支持的Java 8新特性一览
有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分.有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持.本文将带您浏览S ...
- Java 8 新特性终极版
声明:本文翻译自Java 8 Features Tutorial – The ULTIMATE Guide,翻译过程中发现并发编程网已经有同学翻译过了:Java 8 特性 – 终极手册,我还是坚持自己 ...
- Java 8新特性前瞻
快端午小长假了,要上线的项目差不多完结了,终于有时间可以坐下来写篇博客了. 这是篇对我看到的java 8新特性的一些总结,也是自己学习过程的总结. 几乎可以说java 8是目前为止,自2004年jav ...
随机推荐
- Linux串口—struct termios结构体【转】
转自:https://blog.csdn.net/yemingzhu163/article/details/5897156 一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步 ...
- V4L2文档翻译(一)【转】
转自:https://blog.csdn.net/airk000/article/details/23218903 相关资料 https://www.kernel.org/doc/Documentat ...
- Linux系统编程【转】
转自:https://blog.csdn.net/majiakun1/article/details/8558308 一.Linux系统编程概论 1.1 系统编程基石 syscall: libc:标准 ...
- 命令行command line 使用 http proxy的设置方法 Setting Up HTTP Proxy in Terminal
Step 1: Install Shadowsocks Client Shadowsocks is an open-source proxy project to help people visit ...
- python2.7源码或第三方包里埋藏的坑(持续更新)
1.psutil包,aix环境下,如果进程命令过长的话,程序无法取得完整的进程命令,测试代码如下 import psutil proc=psutil.Process(11534558) pidDict ...
- C++:__stdcall详解
原文地址:http://www.cnblogs.com/songfeixiang/p/3733661.html 对_stdcall 的理解(上)在C语言中,假设我们有这样的一个函数:int funct ...
- Ex 5_33 实现一个关于公式长度(其中所有文字总的出现次数)为线性时间的Horn公式可满足性问题_第十次作业
对于所有的蕴含式,生成一张有向图,对于每一个蕴含式,将左边的每一个文字连接到一个中间结点,并用中间结点记录蕴含式左边文字的数量,然后将中间结点连接到蕴含式的右侧结点.例如,对于蕴含式集合 生成的有向图 ...
- 通用jsonp跨域技术获取天气数据
1. 前言 在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题可以使用jsonp技术 2.代码 <!DOCT ...
- linux压缩与解压
1.tar -zcvf /home/aaa.tar.gz /xahot tar -zcvf 打包后生成的文件名全路径 要打包的目录 解压 #tar -zxvf /usr/local/test.tar. ...
- java :: Java中的双冒号操作符
java中的双冒号操作符 定义 双冒号运算操作符是类方法的句柄,lambda表达式的一种简写,这种简写的学名叫eta-conversion或者叫η-conversion. 通常的情况下: 把 x -& ...