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的更多相关文章

  1. Java 8 新特性 - Lambda表达式

    Lambda表达式 vs 匿名类既然lambda表达式即将正式取代Java代码中的匿名内部类,那么有必要对二者做一个比较分析.一个关键的不同点就是关键字 this.匿名类的 this 关键字指向匿名类 ...

  2. 浅析Java 8新特性Lambda Expression

    什么是Lambda Expression 对于Lambda Expression,我的理解是,它是一个函数表达式,如下: (int x, int y) -> x - y 符号左边定义了函数的输入 ...

  3. Java 8新特性--Lambda表达式作为返回值

    lambda表达式作为方法的返回值:

  4. Java 8 新特性--Lambda表达式作为方法参数

    Lambda表达式的使用场景: 当方法的参数是一个函数式接口时,可以使用Lambda表达式进行简化—— 首先,前提是Runnable接口是一个函数式接口,经过查看源码得知,确实如此: 将Runnabl ...

  5. Java 12 新特性介绍,快来补一补

    Java 12 早在 2019 年 3 月 19 日发布,它不是一个长久支持(LTS)版本.在这之前我们已经介绍过其他版本的新特性,如果需要可以点击下面的链接进行阅读. Java 11 新特性介绍 J ...

  6. Java 8 新特性:Lambda、Stream和日期处理

    1. Lambda 简介   Lambda表达式(Lambda Expression)是匿名函数,Lambda表达式基于数学中的λ演算得名,对应于其中的Lambda抽象(Lambda Abstract ...

  7. Spring 4支持的Java 8新特性一览

    有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分.有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持.本文将带您浏览S ...

  8. Java 8 新特性终极版

    声明:本文翻译自Java 8 Features Tutorial – The ULTIMATE Guide,翻译过程中发现并发编程网已经有同学翻译过了:Java 8 特性 – 终极手册,我还是坚持自己 ...

  9. Java 8新特性前瞻

    快端午小长假了,要上线的项目差不多完结了,终于有时间可以坐下来写篇博客了. 这是篇对我看到的java 8新特性的一些总结,也是自己学习过程的总结. 几乎可以说java 8是目前为止,自2004年jav ...

随机推荐

  1. UML和模式应用5:细化阶段(10)---UML交互图

    1.前言 UML使用交互图来描述对象间消息的交互 交互图可以用于动态对象建模. 交互图有两种类型:顺序图和通信图. UML交互图将用来解释和阐述对象设计. 2.顺序图和通信图 顺序图具有丰富的符号标记 ...

  2. myeclipse的web项目导入到eclipse中

    环境组成: java8 eclipse4.4.2 for javaee tomcat 7.0.61 1.导入myeclipse项目 2.设置JDK环境 3.将导入的项目修改为web项目 将myecli ...

  3. Ubungu 18.04安装MySQL 5.7.24

    Ubuntu 18.04,mysql Ver 14.14 Distrib 5.7.24, for Linux (x86_64), USERNAME@USERNAME-VirtualBox:~$ sud ...

  4. 第一个Spring Boot程序

    Windows 10家庭中文版,java version "1.8.0_152", Eclipse Oxygen.1a Release (4.7.1a),Spring Tools ...

  5. robots.txt、humans.txt、.editorconfig、.gitignore、LICENSE.txt、README.md、CHANGLOG.md

    robots.txt搜索引擎查看的时候会查看这个文件,告诉搜索引擎哪些文件可以查看,哪些文件不能查看 当搜索引擎搜索网站的时候,会看有这个文件没,如果有,会通过里面的文件来确定哪些文件能看,哪些文件不 ...

  6. 测试开发之前端——No6.HTML5中的键盘事件

    键盘事件 由键盘触发的事件. 适用于所有 HTML 5 元素: 属性 值 描述 onkeydown script 当按下按键时运行脚本 onkeypress script 当按下并松开按键时运行脚本 ...

  7. VSCode配置python调试环境

    VSCode配置python调试环境 很久之前的一个东东,翻出来看看 VSCode配置python调试环境 * 1.下载python解释器 * 2.在VSCode市场中安装Python插件 * 4.在 ...

  8. C++ code:for loop designs

    1  用for循环编出系列图形 该图形一共10行,每一行增加一个字符,所以应循环10次,每次输出一行.其循环模式为: :i<=;++i) { 输出第i行 换行 } 我们注意到,每一行长度的变化正 ...

  9. wpf Assembly.LoadFile dll GetType 反射 抛异常 不具有由 URI 识别的资源。

    public static void LoadViewFromUri(this Window window, string baseUri) { try { var resourceLocater = ...

  10. 【linux】crontab失效

    在linux上,crontab任务全部使用完整路径,但是任务无效. 检测crontab 服务是否启动, /etc/init.d/cron status /etc/init.d/cron restart