【java】java8 方法引用(Method References)

时间:2022-06-11 17:23:12

原文参看: oracle 官网教程 

方法应用 (Method References)

假设你使用 lambda 表达式 创建一个匿名方法。有时,这个匿名表达式什么都没做,只是 调用了一个 已经存在的方法。这个时候,通过名称 引用 存在的方法会更加清晰。 方法引用就是用来实现这个过程,这种方法更紧凑,是一种更容易阅读的 lambda 表达式。

lambda 这篇文章的 第六小节展示了 方法引用。

方法引用的种类

四类方法引用:

引用一个静态方法: ContainingClass :: staticMethodName

引用一个特定对象 的 实例方法:  containingObject :: instanceMethodName

引用特定类型的任意对象的实例方法: ContainingType :: methodName

引用构造函数: ClassName :: new

案例

java bean 

package com.ycit.bean;

import java.time.LocalDate;

/**
 * 学生类
 *
 * @author xlch
 * @create 2017-05-17 22:15
 */
public class Student {

    private String name;
    private String gender;
    private String address;
    private LocalDate birthday;

    // getter   setter
    // constructor

    /**
     * 静态方法  根据年龄比较
     * @param a
     * @param b
     * @return
     */
    public static int compareByAge(Student a, Student b) {
        return a.birthday.compareTo(b.birthday);
    }
}

测试类:

    @Test
    public void methodReferenceTest() {
        Student zs = new Student("张三", LocalDate.parse("19920803", DateTimeFormatter.ofPattern("yyyyMMdd")));
        Student ls = new Student("李四", LocalDate.parse("19901003", DateTimeFormatter.ofPattern("yyyyMMdd")));
        List<Student> students = new ArrayList<>();
        students.add(zs);
        students.add(ls);
        Student[] studentArray = students.toArray(new Student[students.size()]);

        //原始写法
        Arrays.sort(studentArray, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getBirthday().compareTo(o2.getBirthday());
            }
        });

        // lambda 表达式写法
        Comparator<Student> comparatorLambda =  (a, b) -> a.getBirthday().compareTo(b.getBirthday());
        Arrays.sort(studentArray, comparatorLambda);

        //  ① 静态方法引用
        Comparator<Student> comparatorStatic = Student::compareByAge; // 这里使用的函数接口为 Comparator<T>
        Arrays.sort(studentArray, comparatorStatic);

        //  ② 特定对象的实例方法引用
        ComparisonProvider provider = new ComparisonProvider();
        Comparator<Student> comparatorSpecific = provider::compareByName;
        Arrays.sort(studentArray, comparatorSpecific);

        //  ③ 特定类型的任意对象的实例方法引用
        String[] stringArray ={ "Barbara", "James", "Mary", "John",
                "Patricia", "Robert", "Michael", "Linda" };
        Arrays.sort(stringArray, String::compareToIgnoreCase);
        Arrays.sort(stringArray, (s1, s2) -> s1.compareToIgnoreCase(s2)); // 特定类型的任意对象的实例方法引用 转为 lambda 写法

        //  ④ 构造函数引用
        Supplier<HashSet<Student>> supplier = HashSet::new; // 构造 Supplier 函数式接口
        Supplier<HashSet<Student>> supplier2 = () -> new HashSet<>(); // 构造 Supplier 函数式接口
        Set<Student> r2 = transferElements(students, supplier);
        Set<Student> r3 = transferElements(students, HashSet<Student>::new);
        Set<Student> r1 = transferElements(students, supplier2); // 构造函数引用转化成 lambda 表达式 写法

        // 使用 Comparator 中的方法——lambda 表达式
        Arrays.sort(studentArray, Comparator.comparing(student ->student.getBirthday()));
        // 使用 Comparator 中的方法——方法引用
        Arrays.sort(studentArray, Comparator.comparing(Student::getBirthday));

        Arrays.stream(stringArray).forEach(System.out::println);
        Arrays.stream(studentArray).forEach(student -> System.out.println(student.getName()));

    }

    /**
     *  将元素从一个集合拷贝到另一个集合
     * @param sourceCollection
     * @param collectionFactory
     * @param <T>
     * @param <SOURCE>
     * @param <DEST>
     * @return
     */
    public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>> DEST transferElements(
            SOURCE sourceCollection,
            Supplier<DEST> collectionFactory) {
        DEST result = collectionFactory.get();
        for (T t : sourceCollection) {
            result.add(t);
        }
        return result;
    }