Java新特性--方法引用

常见方法引用

方法引用可以让你重复使用现有的方法定义,并像Lambda一样传递它们。

方法引用可以看做是仅仅调用特定方法的Lambda表达式的一种便捷写法。类似于Lambda表达式,方法引用不能独立存在,总是会转换为函数式接口的实例。

需要使用方法引用时,用::操作符分隔对象(或类名)和方法名,目标引用放在分隔符::前面,方法名放在::后面。

注意,只需要方法名,不需要小括号。

主要有三种情况:

对象::实例方法
Class::静态方法
Class::实例方法

指向静态方法的方法引用

Lambda表达式:(args) -> ClassName.staticMethod(args)
方法引用:ClassName::staticMethod

实例一:

@Test
public void test02(){
    Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
    System.out.println(com1.compare(1, 2));

    Comparator<Integer> com2 = Integer::compare;
    System.out.println(com2.compare(2, 1));
}

示例二:

Integer[] data = {21,90,34,76};
Arrays.sort(data, Integer::compare);//引用静态方法
System.out.println(Arrays.toString(data));

其中Arrays.sort方法解释

static <T> void sort(T[] a, Comparator<? super T> c) 
根据指定的比较器引发的顺序对指定的对象数组进行排序。  

指向任意类型的实例方法的引用

Lambda表达式:
(args0, args1) -> args0.instanceMethod(args1)
args0ClassName类型的一个对象
方法引用:ClassName::instanceMethod

Lambda 参数列表中的第一个参数是方法的调用者,第二个参数是方法的参数时(或不存在时,例如调用JavaBean的get()方法),才能使用 ClassName :: Method

示例一:

@Test
public void test03(){
    BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
    System.out.println(bp1.test("a","b"));

    BiPredicate<String, String> bp2 = String::equals;
    System.out.println(bp2.test("c","c"));
}

其中Predicate的test方法解释

boolean test(T t, U u) 
根据给定的参数来评估这个谓词。  

实例二:

List<String> list = Arrays.asList("ccc", "bbb", "aaa");
list.sort(String::compareTo);//引用实例方法
System.out.println(list);

其中list.sort方法解释:

default void sort(Comparator<? super E> c) 
使用随附的 Comparator排序此列表来比较元素。  

指向现有对象的实例方法的引用

Lambda表达式:(args) -> obj.instanceMethod(args)
方法引用:obj::instanceMethod

示例一:

@Test
public void test01(){
    PrintStream ps = System.out;
    Consumer<String> con1 = (s) -> ps.println(s);
    con1.accept("aaa");

    Consumer<String> con2 = ps::println;
    con2.accept("bbb");
}

示例二:

list.forEach(System.out::println);

构造方法引用

对于一个现有的构造方法,可以使用类名和关键字new来创建一个构造方法的引用:ClassName::new

package com.wangbo.cto.lambda;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @date 2019/11/14 23:08
 * @auther wangbo
 */
public class Test1 {
    public static void main(String[] args) {

        //引用无参数构造方法
        Supplier<Person> supplier = Person::new;
        Person p1 = supplier.get();
        System.out.println(p1);

        //引用有一个参数构造方法
        Function<String, Person> function = Person::new;
        Person p2 = function.apply("wangbo");
        System.out.println(p2);

        //应用有两个参数的构造方法
        BiFunction<String, Integer, Person> biFunction = Person::new;
        Person p3 = biFunction.apply("wangbo", 28);
        System.out.println(p3);

        //如果引用有三个参数及三个以上参数的构造方法,需要自定义匹配的函数式接口
        TriFunction<String, Integer, String, Person> triFunction = Person::new;
        Person p4 = triFunction.myMethod("zhangsan", 90, "男");
        System.out.println(p4);
    }
}
/**
 * 自定义函数式接口
 */
@FunctionalInterface
public interface TriFunction<T, U, V, R>{
    R myMethod(T t, U u, V v);
}
public class Person{
    String name;
    Integer age;
    String gender;

    public Person(){}

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, Integer age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name=" + name +
                ", age=" + age +
                ", gender="+ gender +
                "}";
    }
}

运行结果

Person{name=null, age=null, gender=null}
Person{name=wangbo, age=null, gender=null}
Person{name=wangbo, age=28, gender=null}
Person{name=zhangsan, age=90, gender=男}
原文地址:https://www.cnblogs.com/yanl55555/p/13554962.html