若Lambda体中的内容已经有方法实现过了,我们可以使用方法引用,使用方法引用的时候需要保证引用方法的参数列表和返回值类型与我们当前所要实现的函数式接口方法的参数列表和返回值类型保持一致。方法引用是Lambda表达式的另外一种表现形式。
主要有3种语法格式:
(1)对象::实例方法名
publicvoidtest1(){Consumercon=(x)->System.out.println(x);con.accept("HelloWorld!");PrintStreamps=System.out;//返回一个PrintStream对象//System.out.println(x)在PrintStream的println方法中已经实现,可以使用方法引用Consumercon1=ps::println;con1.accept("HelloLambda!");Consumercon2=System.out::println;//匿名对象方法引用con2.accept("HelloLambdaMethod!");}(2)类::静态方法名
publicvoidtest2(){Comparatorcom=(x,y)->Integer.compare(x,y);com.compare(1,2);//使用方法引用的方式Comparatorcom1=Integer::compare;com1.compare(1,2);}(3)类::实例方法名
前提:第一个参数是实例方法的调用者,第二个参数是实例方法的参数
注意:
1、Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保存一致
2、若Lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method-类::实例方法名
//类::实例方法名@Testpublicvoidtest4(){BiPredicatebp=(x,y)->x.equals(y);booleanbool=bp.test(newString("huang"),"huang");System.out.println(bool);//前提:第一个参数是实例方法的调用者,第二个参数是实例方法的参数//例如x是equal方法的调用者,y是实例方法的参数BiPredicatebp2=String::equals;bool=bp2.test("huang","huang");System.out.println(bool);}二、构造器引用语法格式:ClassName::new
调用哪个构造器取决于函数式接口中的方法形参的定义,Lambda会自动根据接口方法的定义推断你要调用的构造器,也就是说需要调用的构造器的参数列表要与函数式接口中的抽象方法的参数列表保持一致
//构造器引用@Testpublicvoidtest5(){Suppliersup=()->newEmployee();Employeeemp=sup.get();//构造器引用:根据参数列表自动匹配构造器Suppliersup2=Employee::new;emp=sup2.get();System.out.println(emp);}@Testpublicvoidtest6(){Functionfunc=x->newEmployee(x);Employeeemp=func.apply(10);System.out.println(emp);Functionfunc1=Employee::new;emp=func1.apply(10);System.out.println(emp);//BiFunctionbf=Employee::new;编译错误,没有两个Integer构造器}示例1:此时会调用Employee的无参构造器,因为Supplier接口的抽象方法没有入参
示例2:此时Employee中需要一个:一个入参的构造器
示例3:当需求2个入参的构造器时,会编译错误。因为没有默认2个参数的构造器。
同构造器引用,语法格式为Type[]::new
publicvoidtest5(){Functionfun=(x)->newString[x];fun.apply(10);//数组引用Functionfun1=String[]::new;fun1.apply(20);}