9.1、Lambda表达式

9.1.1、标准格式

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

9.1.2、使用前提

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

9.1.3、常见应用

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

interface MyInter {
void show();
} public class Main {
public static void main(String[] args) {
myInterShow(() -> System.out.println("Hello,World"));
} public static void myInterShow(MyInter mi) {
mi.show();
}
}

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

interface MyInter {
void show(String s);
} public class Main {
public static void main(String[] args) {
myInterShow((s) -> System.out.println(s));
} public static void myInterShow(MyInter mi) {
mi.show("Hello,World");
}
}

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

interface MyInter {
int show(int x, int y);
} public class Main {
public static void main(String[] args) {
myInterShow((x, y) -> x + y);
} public static void myInterShow(MyInter mi) {
int show = mi.show(10, 20);
System.out.println(show);
}
}

9.1.4、省略模式

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

9.1.5、注意事项

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

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

    • 根据局部变量的赋值得知Lambda对应的接口
    Runnable r = () -> System.out.println("Hello,World");
    • 根据调用方法的参数得知Lambda对应的接口
    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、方法引用符

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

9.2.3、省略模式

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

9.2.4、常见应用

9.2.4.1、引用类方法

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

interface Converter {
int convert(String s);
} public class Main {
public static void main(String[] args) {
// Lambda写法
useConverter(s -> Integer.parseInt(s));
// 引用的方法
useConverter(Integer::parseInt);
} private static void useConverter(Converter c) {
int number = c.convert("666");
System.out.println(number);
}
}

9.2.4.2、引用类的实例方法

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

interface MyString {
String mySubString(String s, int x, int y);
} public class Main {
public static void main(String[] args) {
// Lambda写法
useMyString((s, x, y) -> s.substring(x, y));
// 引用的方法
useMyString(String::substring);
} private static void useMyString(MyString my) {
String s = my.mySubString("HelloWorld", 2, 5);
System.out.println(s);
}
}

9.2.4.3、引用对象的实例方法

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

class PrintString {
public void printUpper(String s) {
String result = s.toUpperCase();
System.out.println(result);
}
} interface Printer {
void printUpperCase(String s);
} public class Main {
public static void main(String[] args) {
// Lambda写法
usePrinter(s -> System.out.println(s.toUpperCase()));
// 引用的方法
PrintString ps = new PrintString();
usePrinter(ps::printUpper);
} private static void usePrinter(Printer p) {
p.printUpperCase("HelloWorld");
}
}

9.2.4.4、引用构造器方法

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

class Student {
private String name;
private int age; public Student() {} public Student(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
} interface StudentBuilder {
Student build(String name, int age);
} public class Main {
public static void main(String[] args) {
// Lambda写法
useStudentBuilder((name, age) -> new Student(name, age));
// 引用的写法
useStudentBuilder(Student::new);
} private static void useStudentBuilder(StudentBuilder sb) {
Student s = sb.build("林青霞", 30);
System.out.println(s.getName() + "," + s.getAge());
}
}

第九章 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. I/O模式及select、 poll、 epoll

    I/O多路复用技术 复用技术(multiplexing)并不是新技术而是一种设计思想,在通信和硬件设计中存在频分复用.时分复用.波分复用.码分复用等.在日常生活中复用的场景也非常多.从本质上来说,复用 ...

  2. Windows使用VNC远程连接Linux桌面系统

    sudo yum -y install tigervnc-server  #安装 su - your_user #切换用户 vncpasswd #设置密码 sudo cp /lib/systemd/s ...

  3. ORA-39257: Data cannot be remapped for more than 10 columns.

    ORA-39257: Data cannot be remapped for more than 10 columns. 前言 还是脱敏数据相关的事情. 使用expdp的remap_data参数对指定 ...

  4. (私人收藏)精美PPT模板

    精美PPT模板 https://pan.baidu.com/s/1vsRnX5h7t3MZ7qdrFvuI1wsucr

  5. PreparedStatement 防止sql注入 练习

    使用的数据库 MariaDB 10.5.4版本   端口1054     数据库为jt_db,表 为user 数据库的建表和插入相关数据代码: create table user( id int pr ...

  6. efcore 跨表查询,实现一个接口内查询两个不同数据库里各自的表数据

    最近有efcore跨库查询的需求,研究了下colder框架里文档的分库实现,发现并不能完全实现一个接口下的跨库查询请求,只能满足一个业务层构造指定的唯一一个数据库访问接口. 先说下文档是怎么实现的 D ...

  7. Unity音量可视化——粒子随声浪跳动

    起初是看到这么一篇博客 Shader特效-- 音符跳动,效果如下图 具体的shader代码就不贴在这里了,他的博客里都有. 处理音频的关键代码如下: private int m_NumSamples ...

  8. java 面向对象(十一):关键字:package/import

    1.1 使用说明: * 1.为了更好的实现项目中类的管理,提供包的概念 * 2.使用package声明类或接口所属的包,声明在源文件的首行 * 3.包,属于标识符,遵循标识符的命名规则.规范(xxxy ...

  9. RCNN论文阅读笔记

    一摘要: 两个主要工作:1将cnn和自上而下的区域提案结合进行定位和对象分割:2当训练数据稀缺时,先预训练然后微调. rccn工作分为四步:1输入一张图片 2用selective search算法对每 ...

  10. day5:isinstance&代码块&分支&while循环

    1.判断类型 isinstance语法:用法一: isinstance(要判断的值,要判断的类型) 返回True 或者 False用法二: isinstance(要判断的值,(可能的类型1,可能的类型 ...