第九章 Lambda&方法引用

Posted caochenlei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第九章 Lambda&方法引用相关的知识,希望对你有一定的参考价值。

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&方法引用的主要内容,如果未能解决你的问题,请参考以下文章

第九章 接口

第九章 多语言环境的支持和多屏幕的适配

CSS3秘笈复习:第九章&第十章

Git Git 第九章 国内代码托管中心 码云 -- 码云(简介 & 码云帐号注册和登录 & 码云创建远程库 & IDEA 集成码云 & 导入GitHub项目)

javascript高级程序设计 第九章-- 客户端检测

Java 第九章 类的方法 笔记