9.1、Lambda表达式

9.1.1、标准格式

  1. (形式参数) -> {代码块}

9.1.2、使用前提

有一个接口并且接口中有且仅有一个抽象方法

9.1.3、常见应用

9.1.3.1、无参无返回值抽象方法练习

  1. interface MyInter {
  2. void show();
  3. }
  4. public class Main {
  5. public static void main(String[] args) {
  6. myInterShow(() -> System.out.println("Hello,World"));
  7. }
  8. public static void myInterShow(MyInter mi) {
  9. mi.show();
  10. }
  11. }

9.1.3.2、有参无返回值抽象方法练习

  1. interface MyInter {
  2. void show(String s);
  3. }
  4. public class Main {
  5. public static void main(String[] args) {
  6. myInterShow((s) -> System.out.println(s));
  7. }
  8. public static void myInterShow(MyInter mi) {
  9. mi.show("Hello,World");
  10. }
  11. }

9.1.3.3、有参有返回值抽象方法练习

  1. interface MyInter {
  2. int show(int x, int y);
  3. }
  4. public class Main {
  5. public static void main(String[] args) {
  6. myInterShow((x, y) -> x + y);
  7. }
  8. public static void myInterShow(MyInter mi) {
  9. int show = mi.show(10, 20);
  10. System.out.println(show);
  11. }
  12. }

9.1.4、省略模式

  1. 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
  2. 如果参数有且仅有一个,那么小括号可以省略
  3. 如果代码块的语句只有一条,可以省略大括号和分号和return关键字

9.1.5、注意事项

  1. 使用Lambda必须要有接口并且要求接口中有且仅有一个抽象方法

  2. 必须有上下文环境,才能推导出Lambda对应的接口

    • 根据局部变量的赋值得知Lambda对应的接口
    1. Runnable r = () -> System.out.println("Hello,World");
    • 根据调用方法的参数得知Lambda对应的接口
    1. new Thread(() -> System.out.println("Hello,World")).start();

9.1.6、Lambda表达式和匿名内部类的区别

  1. 所需类型不同

    • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
    • Lambda表达式:只能是接口
  2. 使用限制不同
    • 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
    • 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
  3. 实现原理不同
    • 匿名内部类:编译之后,产生一个单独的.class字节码文件
    • Lambda表达式:编译之后,没有一个单独的.class字节码文件,对应的字节码会在运行的时候动态生成

9.2、方法引用

9.2.1、概述

在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案,拿参数做操作,如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?肯定是没必要,那我们又是如何使用已经存在的方案的呢?我们是通过方法引用来使用已经存在的方案

9.2.2、方法引用符

  1. :: 该符号为引用运算符,而它所在的表达式被称为方法引用

9.2.3、省略模式

方法引用可以根据上下文进行推导,方法引用是Lambda的孪生兄弟

9.2.4、常见应用

9.2.4.1、引用类方法

使用说明:Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数

  1. interface Converter {
  2. int convert(String s);
  3. }
  4. public class Main {
  5. public static void main(String[] args) {
  6. // Lambda写法
  7. useConverter(s -> Integer.parseInt(s));
  8. // 引用的方法
  9. useConverter(Integer::parseInt);
  10. }
  11. private static void useConverter(Converter c) {
  12. int number = c.convert("666");
  13. System.out.println(number);
  14. }
  15. }

9.2.4.2、引用类的实例方法

使用说明:Lambda表达式被类的实例方法替代的时候,第一个参数作为调用者,后面的参数全部传递给该方法作为参数

  1. interface MyString {
  2. String mySubString(String s, int x, int y);
  3. }
  4. public class Main {
  5. public static void main(String[] args) {
  6. // Lambda写法
  7. useMyString((s, x, y) -> s.substring(x, y));
  8. // 引用的方法
  9. useMyString(String::substring);
  10. }
  11. private static void useMyString(MyString my) {
  12. String s = my.mySubString("HelloWorld", 2, 5);
  13. System.out.println(s);
  14. }
  15. }

9.2.4.3、引用对象的实例方法

使用说明:Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数

  1. class PrintString {
  2. public void printUpper(String s) {
  3. String result = s.toUpperCase();
  4. System.out.println(result);
  5. }
  6. }
  7. interface Printer {
  8. void printUpperCase(String s);
  9. }
  10. public class Main {
  11. public static void main(String[] args) {
  12. // Lambda写法
  13. usePrinter(s -> System.out.println(s.toUpperCase()));
  14. // 引用的方法
  15. PrintString ps = new PrintString();
  16. usePrinter(ps::printUpper);
  17. }
  18. private static void usePrinter(Printer p) {
  19. p.printUpperCase("HelloWorld");
  20. }
  21. }

9.2.4.4、引用构造器方法

使用说明:Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数

  1. class Student {
  2. private String name;
  3. private int age;
  4. public Student() {}
  5. public Student(String name, int age) {
  6. this.name = name;
  7. this.age = age;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public int getAge() {
  16. return age;
  17. }
  18. public void setAge(int age) {
  19. this.age = age;
  20. }
  21. }
  22. interface StudentBuilder {
  23. Student build(String name, int age);
  24. }
  25. public class Main {
  26. public static void main(String[] args) {
  27. // Lambda写法
  28. useStudentBuilder((name, age) -> new Student(name, age));
  29. // 引用的写法
  30. useStudentBuilder(Student::new);
  31. }
  32. private static void useStudentBuilder(StudentBuilder sb) {
  33. Student s = sb.build("林青霞", 30);
  34. System.out.println(s.getName() + "," + s.getAge());
  35. }
  36. }

第九章 Lambda&方法引用的更多相关文章

  1. JAVA 8 主要新特性 ----------------(五)Lambda方法引用与构造器引用

    一.Lambda方法引用 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!(实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!) 方法引用: 使用操作符 “::” 将 ...

  2. java8 lambda方法引用

    注意引用方法的参数列表与返回值类型要与函数式接口中的抽象方法的参数列表与返回值类型保持一致 主要有三种语法格式: * * 对象::实例方法名 * * 类::静态方法名 * * 类::实例方法名 pub ...

  3. Java自学-Lambda 方法引用

    Lambda 方法引用 步骤 1 : 引用静态方法 首先为TestLambda添加一个静态方法: public static boolean testHero(Hero h) { return h.h ...

  4. Lambda 方法引用

    1.方法引用:若Lambda 体中的内容有方法已经实现了,我们可以使用“引用方法”(可以理解为方法引用是Lambda表达式的另外一种表现形式) 方法引用主要有三种语法格式: ①  对象 :: 实例方法 ...

  5. Lambda语言篇 —— lambda, 方法引用, 目标类型和默认方法

    本文介绍了Java SE 8中新引入的lambda语言特性以及这些特性背后的设计思想.这些特性包括: lambda表达式(又被成为"闭包"或"匿名方法") 方法 ...

  6. Java8新特性 -- Lambda 方法引用和构造器引用

    一. 方法引用: 若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用” 要求 方法的参数和返回值类型 和 函数式接口中的参数类型和返回值类型保持一致. 主要有三种语法格式: 对象 :: ...

  7. Lambda 方法引用 构造器引用 数组引用

    一.方法引用 注意: 1.Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中的抽象方法的函数列表和返回值保持一致!2.若Lambda 参数列表中的第一个参数是实例方法的调用者,而第二个 ...

  8. 《Python基础教程(第二版)》学习笔记 -> 第九章 魔法方法、属性和迭代器

    准备工作 >>> class NewStyle(object): more_code_here >>> class OldStyle: more_code_here ...

  9. 《Python基础教程》 读书笔记 第九章 魔法方法、属性和迭代器(上)

    构造方法 在Python中创建一个构造方法很容易.只要把init方法的名字从简单的init修改为魔法版本__init__即可: >>> class FooBar: ...     d ...

随机推荐

  1. ionic2/Angularjs cordova node.js

    ionic 和 cordova 的区别 环境的搭建{node.js,jdk1.8/jdk1.7,android sdk,intellijIdea,ionic,cordova} nodejs+ionic ...

  2. web前端达到什么水平,才能找到工作?

    前端都需要学什么(可以分为八个阶段)<1>第一阶段: HTML+CSS:HTML进阶. CSS进阶.DIV+CSS布局.HTML+CSS整站开发. JavaScript基础:Js基础教程. ...

  3. Raft论文《 In Search of an Understandable Consensus Algorithm (Extended Version) 》研读

    Raft 论文研读 说明:本文为论文 < In Search of an Understandable Consensus Algorithm (Extended Version) > 的 ...

  4. 一文搞定 Spring Data JPA

    Spring Data JPA 是在 JPA 规范的基础上进行进一步封装的产物,和之前的 JDBC.slf4j 这些一样,只定义了一系列的接口.具体在使用的过程中,一般接入的是 Hibernate 的 ...

  5. .NET WEB API关键过程 思维导图

    背景说明 近期在去面试的过程中,被问及有关WEB API的一些特性,一时竟不知该如何回答,故根据自己已知的知识,加上网上搜索的,详细列举了一下,期望对WEB API有一个比较开阔和全面的认知. 关键要 ...

  6. Window - 安装 Jenkins

    安装方式 war 包放 Tomcat 下 直接安装 jenkins.msi 环境准备 安装 jdk.tomcat,参考:https://www.cnblogs.com/poloyy/p/1326781 ...

  7. mysql修改密码的三种方式

  8. Re5ilio 5ync:资源神器

    文章目录 #0x0 简单的介绍 #0x1 安装使用 #0x10 下载 #0x11 安装 #0x12 升级pro权限 #0x13 开始添加资源 #0x14 后续 一定要小心哦!! #0x0 简单的介绍 ...

  9. Python 字符串改变

    在Python中,字符串是不可变类型,即无法直接修改字符串的某一位字符. 因此改变一个字符串的元素需要新建一个新的字符串. 常见的修改方法有以下4种. 方法1:将字符串转换成列表后修改值,然后用joi ...

  10. 记一次WPF程序带参数启动

    问题:总共有两个程序.第一个程序使用Process带参数启动第二个程序. 网上一堆人都说什么重写Main入口啊 什么的.然后还一堆人跟着复制发文章.我也是醉了,简直是坑人.为何要舍近求远,直接重写AP ...