方法引用
- 什么是方法引用:通过方法的名字来指向一个方法的的方式叫做 方法引用 ——引用而不调用
- 特征:操作符
::
- 本质:Lambda 表达式的快捷写法
- 使用说明
- 该方法已经存在或者是构造方法
- 如果该方法存在入参,需要借助foreach循环实现
- 如果该方法的返回类型是
void
,则默认会使用Consumer<T>
接口或者其子接口 - 如果该方法的返回类型不是
void
,则需要手动声明使用Function<T>、Supplier<T>、Predicate<T>
接口或者其子接口
- 示例——四种类型的方法的方法引用——消费性与创造型
public class Car {
private static Car create(final Supplier<Car> supplier) {
return supplier.get();
}
private static void collide(final Car car) {
System.out.println("Collided " + car.toString());
}
private void repair() {
System.out.println("Repaired " + this.toString());
}
private void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
@Test
public void test1(){
//构造器引用:它的语法是Class::new,或者更一般的Class< T >::new实例如下:
//隐式声明为Supplier<T>
final Car car = Car.create(Car::new);
//等价于
Supplier<Car> supplier = () -> new Car();
final Car car1 = Car.create(supplier);
List<Car> carList = Arrays.asList(car);
//静态方法引用:它的语法是Class::static_method,实例如下:
//隐式声明为Consumer<T>
carList.forEach(Car::collide);
//等价于
Consumer<Car> carConsumer = var1 -> collide(var1);
carList.forEach(carConsumer);
//特定类的任意对象的方法引用:它的语法是Class::method实例如下:
//隐式声明为Consumer<T>
carList.forEach(Car::repair);
//等价于
Consumer<Car> carConsumer1 = var2 -> repair();
carList.forEach(carConsumer1);
final Car car2 = Car.create(Car::new);
//特定对象的方法引用:它的语法是instance::method实例如下:
//隐式声明为Consumer<T>
carList.forEach(car2::follow);
//等价于
Consumer<Car> carConsumer2 = var3 -> follow(var3);
carList.forEach(carConsumer2);
}
}
四种方法的引用,构造方法默认使用的是Supplier接口,而其他三种因为返回类型是void,所以默认使用的都是Consumer接口。
- 示例——操作型
@Test
public void test(){
IntUnaryOperator intUnaryOperator = e->e;
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(7);
list.add(2);
list.sort(comparing(intUnaryOperator::applyAsInt).reversed());
list.forEach(System.out::println);
}
IntUnaryOperator
是 Function
接口的子接口
- 示例——断言型
@Test
public void test2(){
Predicate<Integer> predicate = e -> e >=5;
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(7);
list.add(2);
eval(list,predicate::test);
//事实上,这毫无意义,,,完全可以替代为
//eval(list,predicate);
}
private void eval(List<Integer> list, Predicate<Integer> predicate) {
for(Integer n: list) {
if(predicate.test(n)) {
System.out.print(n + " ");
}
}
}