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 ...
随机推荐
- HDFS安全模式
用户可以通过dfsadmin -safemode value 来操作安全模式,参数value的说明如下: enter - 进入安全模式 leave - 强制NameNode离开安全模式 get - 返 ...
- Linux系统打开core dump的配置【转】
什么是core dump core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.core du ...
- C/C++:.hpp与.h区别
原文地址:http://blog.csdn.net/f_zyj/article/details/51735416 .hpp,本质就是将.cpp的实现代码混入.h头文件当中,定义与实现都包含在同一文件, ...
- 003_饿了么chaosmonkey实现
背景 公司目前的服务设计大部分满足 design for failure 理念.随着业务复杂度的提升,我们很难再保证对系统故障的容错性.我们需要工具来验证服务的容错性,基于这个需求我们使用了 tc 工 ...
- python操作haproxy.cfg文件
需求 1.查 输入:www.oldboy.org 获取当前backend下的所有记录 2.新建 输入: arg = { 'bakend': 'www.oldboy.org', 'record':{ ' ...
- servlet请求中的信息
在servlet中HttpServeltRequest中有一个方法getRequestURL() 假如我们平常输入的地址是:localhost/Demo1/TestServlet?hello=worl ...
- asp.net core 2.0 api ajax跨域问题
API配置: services.AddCors(options => { options.AddPolicy("any", builder => { builder.W ...
- 持续集成一:git上传代码
先注册一个账号,注册地址:https://github.com/ 记住地址 下载git本地客户端,下载地址:https://git-scm.com/download/win 一路next傻瓜安装,加入 ...
- python接口自动化测试六:时间戳,防重复处理
对于不可重复参数,可以用时间戳,防重复 import time title = '这是我的标题:%s'%str(int(time.time())) print(title) 转化成时间格式 t = t ...
- python3的unittest中使用test suite(测试套件)执行指定测试用例
示例代码 module.py class baidumodule(): def __init__(self,driver,): self.dr = driver #不能在类中再次导入webdriver ...