方法引用
将现有方法的调用转化为函数对象
表达形式
例子:
- 类型+静态方法:
Math::max
:(int a, int b) -> Math.max(a, b);
逻辑:就是执行静态方法
参数:静态方法的参数
比如:Math::abs
-> Math.abs(n)
-> n -> Math.abs(n)
- 类型+非静态方法:
Student::getName
:(student stu) -> stu.getName();
- 对象+非静态方法:
System.out::println
:(object obj) -> System.out.println(obj);
- 类型+new 关键字:
Student::new
:() -> new Student();
函数对象内部逻辑就是为了调用方法,参数部分就是调用方法需要传入的未知的部分
表述练习
1.写出等价的Lambda表达式
应用例子:
静态方法引用方式
1.通过方法引用的形式打印Stream流中的每个元素
import java.util.stream.Stream;
public class Exercise4 {
public static void main(String[] args) {
Stream.of(
new Animal("小黄", "猫"),
new Animal("小花", "狗"),
new Animal("旺财", "狗")
)
// .forEach(animal -> System.out.println(animal)); //Lambda表达式传入
.forEach(Exercise4::printAnimal);
/*
1、先写出Lambda表达式类型的方法 : (Animal animal) -> System.out.println(animal)
2、推出需要传入的函数对象形式: 按住Ctrl + P:得知forEach()需要传入Consumer<? super Animal>的静态方法
3、实现传入Animal类型,无返回值的静态方法: printAnimal(Animal animal)
4、将其转化成函数对象传入forEach(): Exercise::printAnimal 等同于 animal -> printAnimal(animal)
*/
}
public static void printAnimal(Animal animal) {
System.out.println(animal);
}
record Animal(String name , String species) {
}
}
要点
- 函数对象的逻辑就是执行此静态方法。为了执行该静态方法,就需要把未知的部分作为函数对象的参数
2.挑选出Stream流中特定的元素
是案例1中的进阶,是需要先挑选出物种为狗的元素然后打印
import java.util.stream.Stream;
public class Exercise4 {
public static void main(String[] args) {
Stream.of(
new Animal("小黄", "猫"),
new Animal("小花", "狗"),
new Animal("旺财", "狗")
)
// .forEach(animal -> System.out.println(animal)); //Lambda表达式传入
// .filter(animal -> animal.species.equals("狗")) //Lambda表达式传入
.filter(Exercise4::isDog)
.forEach(Exercise4::printAnimal);
/*
1、先写出Lambda表达式类型的方法 : (Animal animal) -> System.out.println(animal)
2、推出需要传入的函数对象形式: 按住Ctrl + P:得知forEach()需要传入Consumer<? super Animal>的静态方法
3、实现传入Animal类型,无返回值的静态方法: printAnimal(Animal animal)
4、将其转化成函数对象传入forEach(): Exercise::printAnimal 等同于 animal -> printAnimal(animal)
*/
}
public static boolean isDog(Animal animal) {
return animal.species.equals("狗");
}
public static void printAnimal(Animal animal) {
System.out.println(animal);
}
record Animal(String name , String species) {
}
}
分析:
- 先写出Lambda表达式形式的函数对象传入
filter()
看结果 - 按住Ctrl+P看
filter()
需要传入的函数对象形式: 参数类型: Animal 返回值: boolean
- 实现对应的静态方法:
isDog(Animal animal)
- 将其转换成函数对象传入方法中:
Exercise4::isDog
非静态方法引用方式
改写静态方法引用
import java.util.stream.Stream;
public class Exercise4 {
public static void main(String[] args) {
Stream.of(
new Animal("小黄", "猫"),
new Animal("小花", "狗"),
new Animal("旺财", "狗")
)
// .forEach(animal -> System.out.println(animal)); //Lambda表达式传入
// .filter(animal -> animal.species.equals("狗")) //Lambda表达式传入
.filter(Animal::isDog)
.forEach(Animal::printAnimal);
}
record Animal(String name , String species) {
public boolean isDog() {
return this.species.equals("狗");
}
public void printAnimal() {
System.out.println(this);
}
}
}
- 直接引用类中预定义的非静态方法
对象::非静态方法
import java.util.stream.Stream;
public class Exercise4 {
public static void main(String[] args) {
Util util = new Util();
Stream.of(
new Animal("小黄", "猫"),
new Animal("小花", "狗"),
new Animal("旺财", "狗")
)
// .forEach(animal -> System.out.println(animal)); //Lambda表达式传入
// .filter(animal -> animal.species.equals("狗")) //Lambda表达式传入
.filter(util::isDog) //对象+非静态方法: 先定义一个Util对象,然后调用里面的非静态方法
//.forEach(Animal::printAnimal);
.forEach(System.out::println);
}
static class Util {
public boolean isDog(Animal animal) {
return animal.species.equals("狗");
}
}
record Animal(String name , String species) {
}
}
类名::new
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
public class Exercise5 {
static class Animal {
String name = "宠物";
String species = "物种";
public Animal() {
}
public Animal(String name) {
this.name = name;
}
public Animal(String name, String species) {
this.name = name;
this.species = species;
}
@Override
public String toString() {
return "Animal [name=" + name + ", species=" + species + "]";
}
}
public static void main(String[] args) {
Supplier<Animal> animal1 = Animal::new;
Function<String, Animal> animal2 = Animal::new;
BiFunction<String, String, Animal> animal3 = Animal::new;
System.out.println(animal1.get());
System.out.println(animal2.apply("小黄"));
System.out.println(animal3.apply("旺财", "狗"));
}
}