若 Lambda 体中的功能,已经有方法提供了实现,可以使用方法引用(可以将方法引用理解为 Lambda 表达式的另外一种表现形式)
对象的引用 :: 实例方法名
基本使用
@Test public void test(){ Consumer<String> consumer=(x)->System.out.println(x); /* println方法是已经有实现的,可以使用方法引用 */ PrintStream printStream1=System.out; Consumer<String> consumer1=(x)->printStream1.println(x); PrintStream printStream=System.out; Consumer<String> consumer2=printStream::println; /* 方法引用的方式适用于Lambda体中的内容已经有方法实现了 */ Consumer<String> consumer3=System.out::println; consumer3.accept("hello"); }
实例
@Test public void test(){ Employee emp = new Employee(20201116, "zhai", 18, 9999.99); Supplier<String> sup = () -> emp.getName(); System.out.println(sup.get()); System.out.println("----------------------------------"); Supplier<String> sup2 = emp::getName; System.out.println(sup2.get()); }
类名::静态方法名
@Test public void test(){ Comparator<Integer> com = (x, y) -> Integer.compare(x, y); System.out.println(com.compare(12,45)); System.out.println("-------------------------------------"); Comparator<Integer> com2 = Integer::compare; System.out.println(com2.compare(40,40)); }
-1 ------------------------------------- 0
两个输入一个输出的函数式接口
@Test public void test(){ BiFunction<Double, Double, Double> fun = (x, y) -> Math.max(x, y); System.out.println(fun.apply(1.5, 22.2)); System.out.println("--------------------------------------------------"); BiFunction<Double, Double, Double> fun2 = Math::max; System.out.println(fun2.apply(1.2, 1.5)); }
类名::实例方法名
若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
@Test public void test(){ BiPredicate<String, String> bp = (x, y) -> x.equals(y); System.out.println(bp.test("abcde", "abcde")); System.out.println("-----------------------------------------"); BiPredicate<String, String> bp2 = String::equals; System.out.println(bp2.test("abc", "abc")); }
true ----------------------------------------- true
构造器引用
不传递参数的时候调用的是无参的构造器
@Test public void test(){ Supplier<Employee> sup = () -> new Employee(); System.out.println(sup.get()); System.out.println("------------------------------------"); Supplier<Employee> sup2 = Employee::new; System.out.println(sup2.get()); }
Employee(id=0, name=null, age=0, salary=0.0) ------------------------------------ Employee(id=0, name=null, age=0, salary=0.0)
给构造器传递参数
@Test public void test(){ Function<Integer,Employee> function=(s)->new Employee(s); Employee employee1=function.apply(202011); System.out.println(employee1); Function<Integer,Employee> fun2=Employee::new; Employee employee=fun2.apply(202012); System.out.println(employee); }
注意:构造器的参数列表,需要与函数式接口中参数列表保持一致
@Test public void test(){ Function<Integer, String[]> fun = (args) -> new String[args]; String[] strs = fun.apply(10); System.out.println(strs.length); System.out.println("--------------------------"); Function<Integer, Employee[]> fun2 = Employee[] :: new; Employee[] emps = fun2.apply(20); System.out.println(emps.length); }
运用匿名内部类可以省略掉接口的实现类的书写,Lambda表达式可以对匿名内部类进一步简化,方法引用和Lambda表达式的结合使用能够进一步简化代码,但是简化的程度没有Lambda表达式对匿名内部类简化程度大。好处就是能够在Lambda表达式的基础上进一步简化代码。