Java 8新特性 - (3)方法引用
方法引用(Method references)。方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,可以使语言的构造更紧凑简洁,减少冗余代码。
方法引用使用到的操作符“::”,这个操作符把方法引用分成两边,左边是类名或者某个对象的引用,右边是方法名。引用方法有下面几种方式:
- 对象引用::实例方法名
- 类名::静态方法名
- 类名::实例方法名
- 类名::new
- 类型[]::new
对象引用::实例方法名
创建了一个PersonCompare对象,调用了其内部的compareByName实例方法。
public class PersonCompare {
public int compareByName(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
public int compareByAge(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
@Test
public void test(){
Person[] pArr = new Person[]{
new Person("1", LocalDate.of(2019, 12, 1)),
new Person("2", LocalDate.of(2019, 12, 2)),
new Person("3", LocalDate.of(2019, 12, 3)),
new Person("4", LocalDate.of(2019, 12, 4))};
PersonCompare personCompare = new PersonCompare();
Arrays.sort(pArr, personCompare::compareByName);
}
}
类名::静态方法名
举几个例子:
String::valueOf,等价于 Lambda:s -> String.valueOf(s)
Math::pow 等价于lambda表达式 (x, y) -> Math.pow(x, y);
Person::compareByAge 就是一个静态方法引用,也是前面我们举得例子。
Function<Long, Long> f = Math::abs;
Long result = f.apply(-3L);
Math是一个类而abs为该类的静态方法。Function中的唯一抽象方法apply方法参数列表与abs方法的参数列表相同,都是接收一个Long类型参数。
类名::实例方法名
若Lambda表达式的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,就可以使用这种方法:
BiPredicate<String, String> b = String::equals;
b.test("abc", "abcd");
String是一个类而equals为该类的定义的实例方法。BiPredicate中的唯一抽象方法test方法参数列表与equals方法的参数列表相同,都是接收两个String类型参数。
类名::new
在引用构造器的时候,构造器参数列表要与接口中抽象方法的参数列表一致。对应的 Lambda:() -> new String()。
class PersonFactory {
private Supplier<Person> supplier;
public PersonFactory(Supplier<Person> supplier) {
this.supplier = supplier;
}
public Person getPerson() {
return supplier.get();
}
}
PersonFactory factory = new PersonFactory(Person::new);
Person p1 = factory.getPerson();
上面这段代码的功能就是使用PersonFactory工厂,然后使用Person::new创建一个Person实例。
类型[]::new
引用数组和引用构造器很像,格式为 类型[]::new,等价于 lambda 表达式 x -> new int[x]。其中类型可以为基本类型也可以是类。
Function<Integer, int[]> fun = int[]::new;
int[] arr = fun.apply(10);
Function<Integer, Integer[]> fun2 = Integer[]::new;
Integer[] arr2 = fun2.apply(10);
参考: