方法引用
如果我们在Lambda中所指定的操作方案,在其它地方存在相同方案,那是否还有必要再写重复逻辑?
如果Lambda体中的内容有方法已经实现了,我们可以使用"方法引用"
方法引用分为:方法引用、构造器引用和数组引用
1、方法引用
格式分为5种,分别为:
- 对象::实例方法名
- 类::静态方法名
- 类::实例方法名
- super::实例方法名
- this::实例方法名
注意:
- 双冒号 :: 为引用运算符,而它所在的表达式被称为方法引用
- Lambda体中调用方法的参数列表和返回值类型,要与函数式接口中抽象方法的参数列表和返回值类型保持一致
- 若Lambda参数列表中有且仅有一个参数,且该参数是实例方法的调用者;或参数列表中有2个参数,且第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,请使用上面的第3种格式
实例代码如下:
1)通过对象名引用实例方法
//案例:打印输出一个字符串
Consumer<String> con1 = s ->System.out.println(s);//Lambda
con1.accept("hello");
Consumer<String> con2 = System.out::println;//方法引用
con2.accept("hello");
2)通过类名引用静态方法
//需求1:求一个数的绝对值
Function<Integer,Integer> fun1 = i->Math.abs(i);//Lambda
System.out.println(fun1.apply(-10));
Function<Integer,Integer> fun2 = Math::abs;//方法引用
System.out.println(fun2.apply(-10));
//需求2:获取两个整数进行比较的比较器
Comparator<Integer> com1 = (a,b)->Integer.compare(a, b);//Lambda
Comparator<Integer> com2 = Integer::compare;//方法引用
3)通过类名引用实例方法
//需求1:比较2个字符串是否相等
BiPredicate<String, String> bp1 = (s1,s2)->s1.equals(s2);//Lambda
System.out.println(bp1.test("he","he"));
BiPredicate<String, String> bp2 = String::equals;//方法引用
System.out.println(bp2.test("he","he"));
//需求2:获取指定字符串的哈希码值
Function<String,Integer> fun1 = s->s.hashCode();
System.out.println(fun1.apply("hei"));
Function<String,Integer> fun2 = String::hashCode;
System.out.println(fun2.apply("hei"));
4)通过super引用实例方法
@FunctionalInterface
interface Greenable{
void green();
}
class Father{
public void show(){
System.out.println("fu");
}
}
class Son extends Father{
@Override
public void show() {
System.out.println("zi");
}
public void fun(){
method(()->new Father().show());
method(()->super.show());
method(super::show);
}
public void method(Greenable greenable){
greenable.green();
}
}
5)通过this引用实例方法
示例代码如下:
@FunctionalInterface
interface Richable{
void buy();
}
class Husband{
private void buyHouse(){
System.out.println("买套房子");
}
private void marry(Richable rich){
rich.buy();
}
public void beHappy(){
marry(()->this.buyHouse());
marry(this::buyHouse);
}
}
2、构造器引用
格式:
类名称::new
注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致
示例代码如下:
class Student{
String name;
int age;
public Student(){}
public Student(String name){
this.name = name;
}
public Student(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
public class MethodReferenceDemo {
@Test
public void test(){
//调用无参构造
Supplier<Student> sup1 = () -> new Student();//Lambda
System.out.println(sup1.get());
Supplier<Student> sup2 = Student::new;//构造器引用
System.out.println(sup2.get());
//调用一个参数构造
Function<String,Student> fun1 = s -> new Student(s);//Lambda
System.out.println(fun1.apply("张三"));
Function<String,Student> fun2 = Student::new;//构造器引用
System.out.println(fun2.apply("张三"));
//调用两个参数构造
BiFunction<String, Integer, Student> biFun1 = (n,a)->new Student(n,a);//Lambda
System.out.println(biFun1.apply("张三丰", 11));
BiFunction<String, Integer, Student> biFun2 = Student::new;//构造器引用
System.out.println(biFun2.apply("张三丰", 11));
}
}
3、数组引用
格式:
数组类型::new
示例代码如下:
//创建1个长度为10的字符串数组
Function<Integer,String[]> fun1 = i -> new String[i];//Lambda
System.out.println(Arrays.toString(fun1.apply(10)));
Function<Integer,String[]> fun2 = String[]::new;//数组引用
System.out.println(Arrays.toString(fun2.apply(10)));