学习本节需要对lambda表达式有一定掌握(笔者的java8新特性专栏已经有过讲解),对于idea可能只需要会写lambda表达式,可以转为方法引用的时候,idea会有提示,但是如果看别人的代码,别人写了方法引用,还是需要掌握方法引用才能看懂的,所以推荐按部就班的学习。
目录
一.方法引用
1.概述
2.使用过程的三种情况
第一种情况:对象 :: 非静态方法
第二种情况:类 :: 静态方法
第三种情况:类 :: 非静态方法
二.构造器引用
三.数组引用
一.方法引用 1.概述
本质:方法引用本质上就是lambda表达式,是对lambda进一步简化。
使用情景:当传递给lambda表达式的方法体已经有实现的方法了,不需要自己写了,就可以使用方法引用了
使用格式: 类(对象):: 方法名
快速入门案例:
consumer是一个函数式接口,对该接口的应用需要重写accept方法,此时可以采用lambda表达式进行简化。重写的方法体为System.out.println(str); 该方法体已经有已经存在的方法了(系统内置的PrintStream类,该类有方法println,可以直接引用),完全满足方法引用的使用情景。将lambda表达式转换为方法引用System.out::println
public class MR {
@Test
public void test1(){
// 消费型接口 Consumer 传一个参数没有返回 void accept(T t);
Consumer consumer = str -> System.out.println(str);
consumer.accept("记得点赞");
// 对于consumer需要重写的accept方法,方法体为System.out.println(str)
// 已经有实现的方法了 System.out为PrintStream类,该类有方法println,可以直接引用
Consumer consumer1 = System.out::println;
}
}
如果还是不太理解,后面会举更多🌰
2.使用过程的三种情况 第一种情况:对象 :: 非静态方法 第二种情况:类 :: 静态方法情况1、2使用要求:实现函数式接口,该接口抽象方法的形参列表和返回值类型与方法引用的形参列表和返回值类型要一样
举例介绍(注释详解):
public class MR {
@Test
//情况一:对象 :: 非静态方法
//供给型接口 Supplier 无传参有返回 T get();实现Supplier接口时可以使用lambda表达式简化;
//getName方法形参列表和返回值类型都和get方法一致,可以使用方法引用简化lambda表达式
public void test2(){
Employee employee = new Employee(1, "mc");
// lambda表达式
Supplier supplier = ()-> employee.getName();
System.out.println(supplier.get()); //mc
// 方法引用
Supplier supplier1 = employee::getName;
System.out.println(supplier1.get()); //mc
}
//情况二:类 :: 静态方法
//Comparator被注解@FunctionalInterface修饰,可为函数式接口,有抽象方法compare,实现Comparator接口时可以使用lambda表达式简化;
//Integer的compare方法形参列表和返回值类型都和Comparator的compare方法一致,,可以使用方法引用简化lambda表达式
public void test3(){
// lambda表达式
Comparator comparator = (n1,n2) -> Integer.compare(n1,n2);
System.out.println(comparator.compare(2,1)); //1
// 方法引用
Comparator comparator1 = Integer::compare;
System.out.println(comparator1.compare(1,2)); //-1
}
}
@Data
@NoArgsConstructor
class Employee{
private int id;
private String name;
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
}
第三种情况:类 :: 非静态方法
第三种情况特殊一点,并不需要抽象方法的形参列表与方法引用的形参列表要一样;但返回值类型要一样。当然不是所有只要返回值类型一样都可以使用方法引用,看代码会清晰理解。
@Test
//情况三:类 :: 非静态方法
//Comparator int compare(T o1, T o2);
//String int o1.compareTo(o2)
public void test4(){
// lambda表达式
Comparator comparator = (s1,s2) -> s1.compareTo(s2);
System.out.println(comparator.compare("mc","pp")); //-3
// 方法引用
Comparator comparator1 = String :: compareTo;
System.out.println(comparator1.compare("mc","pp")); //-3
}
@Test
//BiPredicate boolean test(T t1, U t2);
//String boolean t1.equals(t2)
public void test5(){
// lambda表达式
BiPredicate biPredicate = (s1,s2) -> s1.equals(s2);
System.out.println(biPredicate.test("s","s")); //true
// 方法引用
BiPredicate biPredicate1 = String::equals;
System.out.println(biPredicate1.test("s","s")); //true
}
二.构造器引用
本质:构造器引用,和方法引用同理,只是使用的是new方法
使用说明:函数式接口的形参列表和构造器的形参列表一致,该接口的返回值类型即为构造器所属类的类型
public void test6(){
//无参构造器,返回一个Employee对象
// lambda表达式
Supplier employee = () -> new Employee();
// 构造器引用
Supplier employee1 = Employee::new;
//传递id,name两个参数,返回一个Employee对象
// lambda表达式
BiFunction employeeBiFunction= (i,str)-> new Employee(i,str);
// 构造器引用
BiFunction employeeBiFunction1 = Employee::new;
employeeBiFunction1.apply(1,"mc");
}
@Data
@NoArgsConstructor
class Employee{
private int id;
private String name;
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
}
三.数组引用
本质:特殊的构造器引用
使用说明:将数组看成一个类,写法和构造器引用就一致了
public void test7(){
// lambda表达式
Function function = length -> new String[length];
System.out.println(Arrays.toString(function.apply(2)));
// 数组引用
Function function1 = String[]::new;
System.out.println(Arrays.toString(function1.apply(2)));
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)