- 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
- 方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖
- 要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!
- 格式:使用操作符 “::” 将类(或对象)与方法名分隔开来
- 如下三种主要使用情况
- 对象 ::实例方法名
- 类 ::静态方法名
- 类 ::实例方法名
方法引用的使用场景
- 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
- 方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例。所以方法引用,也是函数式接口的实例
方法引用使用的要求
- 要求接口中的 抽象方法的形参列表和返回值类型 与 方法引用的方法的形参列表和返回值类型相同!
1、对象::实例方法
1.1、Consumer
Consumer 中 的 void accept (T t)
PrintStream 中 的 void println (T t)
1.2、Supplier
- Supplier 中的 T get()
- Employee 中的 String getName()
package com.methodreference; import org.junit.Test; import java.io.PrintStream; import java.util.function.Consumer; import java.util.function.Supplier; public class MethodRefTest { // 情况一:对象::实例方法 // Consumer 中的 void accept(T t) // PrintStream 中的 void println(T t) @Test public void test1() { Consumercon1 = str -> System.out.println(str); con1.accept("方法的引用");//方法的引用 System.out.println("============="); PrintStream ps = System.out; Consumercon2 = ps::println; con2.accept("方法的引用");//方法的引用 Consumercon3 = System.out::println; con3.accept("方法的引用");//方法的引用 } //Supplier中的 T get() //Employee中的 String getName() @Test public void test2() { Employee emp = new Employee(1001, "Tom", 23, 5600); Suppliersup1 = () -> emp.getName(); System.out.println(sup1.get());//Tom System.out.println("================="); //方法引用 Suppliersup2 = emp::getName; System.out.println(sup2.get());//Tom } class Employee { private Integer id; private String name; private Integer age; private Integer salary; public Employee() { } public Employee(Integer id, String name, Integer age, Integer salary) { this.id = id; this.name = name; this.age = age; this.salary = salary; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getSalary() { return salary; } public void setSalary(Integer salary) { this.salary = salary; } } }
2、类::静态方法
2.1、Comparator
- Comparator 中的 int compare(T t1,T t2)
- Integer 中 的int compare(T t1,T t2)
2.2、Function
- Function 中的 R apply(T t)
- Math 中的 Long round (Double d)
//情况二:类::静态方法 //Comparator中的int compare(T t1,T t2) //Integer中的int compare(T t1,T t2) @Test public void test3() { Comparatorcom1 = (t1, t2) -> Integer.compare(t1, t2); System.out.println(com1.compare(12, 21));//-1 System.out.println("============="); Comparatorcom2 = Integer::compare; System.out.println(com2.compare(12, 21));//-1 } //Function 中的 R apply(T t) //Math中的Long round(Double d) @Test public void test4() { Functionfunc1 = d -> Math.round(d); System.out.println(func1.apply(23.23));//23 System.out.println("=========="); Functionfunc2 = Math::round; System.out.println(func2.apply(-45.78));//-46 }
3、类::实体方法(有难度)
3.1、Comparator
- Comparator 中的 int compare(T t1,T t2)
- String 中的 int t1.compareTo(t2)
3.2、BiPredicate
- BiPredicate 中的 boolean test(T t1,T t2)
- String 中的 boolean t1.equals(t2)
3.3、Function
- Function 中的 R apply(T t)
- Employee 中的 String getName()
//情况三:类::实例方法(有难度) //Comparator 中的 int compare(T t1,T t2) //String 中的 int t1.compareTo(t2) @Test public void test5() { Comparatorcom1 = (t1, t2) -> t1.compareTo(t2); System.out.println(com1.compare("23", "34"));//-1 System.out.println("==============="); Comparatorcom2 = String::compareTo; System.out.println(com2.compare("abd", "abm"));//-9 } //BiPredicate 中的boolean test(T t1,T t2) //String 中的boolean t1.equals(t2) @Test public void test6() { BiPredicatepre1 = (s1, s2) -> s1.equals(s2); System.out.println(pre1.test("abc", "abc"));//true System.out.println("====================="); BiPredicatepre2 = String::equals; System.out.println(pre1.test("97", "a"));//false } //Function 中的 R apply(T t) //Employee 中的String getName() @Test public void test7() { Employee employee = new Employee(1001, "jerry", 23, 2900); Functionfunc1 = e -> e.getName(); System.out.println(func1.apply(employee));//jerry System.out.println("===================="); Functionfunc2 = Employee::getName; System.out.println(func2.apply(employee));//jerry }
一、构造器引用
- 和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。抽象方法的返回值类型即为构造器所属的类的类型。
package com.methodreference; import org.junit.Test; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; public class ConstructRefTest { class Employee { private Integer id; private String name; private Integer age; private Integer salary; public Employee() { System.out.println("方法的引用构造器引用"); } public Employee(Integer id) { this.id = id; } public Employee(Integer id, String name) { this.id = id; this.name = name; } public Employee(Integer id, String name, Integer age, Integer salary) { this.id = id; this.name = name; this.age = age; this.salary = salary; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getSalary() { return salary; } public void setSalary(Integer salary) { this.salary = salary; } @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", salary=" + salary + '}'; } } //构造器引用 //Supplier 中的 T get() //Employee的空参构造器:Employee() @Test public void test1() { Suppliersup = new Supplier () { @Override public Employee get() { return new Employee(); } }; Suppliersup1 = () -> new Employee(); System.out.println(sup1.get());//方法的引用构造器引用 // Employee{id=null, name='null', age=null, salary=null} } //Function中的 R apply(T t) @Test public void test2() { Functionfunc1 = id -> new Employee(id); System.out.println(func1.apply(100));//Employee{id=100, name='null', age=null, salary=null} Functionfunc2 = Employee::new; System.out.println(func2.apply(200));//Employee{id=200, name='null', age=null, salary=null} } //BiFunction 中的 R apply(T t,U u) @Test public void test3() { BiFunctionfunc1 = (id, name) -> new Employee(id, name); System.out.println(func1.apply(1222, "小明"));//Employee{id=1222, name='小明', age=null, salary=null} System.out.println("============="); BiFunctionfunc2 = Employee::new; System.out.println(func2.apply(1000, "小兰"));//Employee{id=1000, name='小兰', age=null, salary=null} } }
二、数组引用
- 大家可以把数组看做是一个特殊的类,则写法与构造器引用一致。
//数组引用 //Function 中的 R apply(T t) @Test public void test4() { Functionfunc1 = length -> new String[length]; System.out.println(Arrays.toString(func1.apply(4)));//[null, null, null, null] System.out.println("================"); Functionfunc2 = String[]::new; System.out.println(Arrays.toString(func2.apply(4)));//[null, null, null, null] }