java中的方法引用

方法引用可以看做式lambda表达式的语法糖, 用于替换lambda表达式,使代码更加精简,我们可以将方法引用看做是一个函数指针, 指向被引用的方法其能够替代lambda表达式的原因在于某些lambda表达式的参数,返回值,功能实现与被引用的方法皆一致.方法引用共分4类:

1. 类名::静态方法名
@Data
@AllArgsConstructor
public class Student {
    private String name;
    private Integer score;
    public static int compareStudentByScore(Student s1, Student s2) {
        return s1.getScore() - s2.getScore();
    }
    public static int compareStudentByName(Student s1, Student s2) {
        return s1.getName().compareToIgnoreCase(s2.getName());
    }
}
@Test
public void Test() {
        Student s1 = new Student("a", 10);
        Student s2 = new Student("b", 90);
        Student s3 = new Student("c", 50);
        Student s4 = new Student("d", 40);

        List<Student> students = Arrays.asList(s1, s2, s3, s4);

        // 传统lambda方式排序
        students.sort((x, y) -> Student.compareStudentByScore(x, y));
        students.forEach(System.out::println);
        System.out.println("---------------");
        // 利用方法引用排序, 不用传参数在于编译器的自动推断
        students.sort(Student::compareStudentByScore);
        students.forEach(System.out::println);
}
注意:这两个完全不一样,不要搞混了:
classname::staticmethod 方法引用,是个指针
classname.staticmethod 方法的调用
2. 引用名(对象名)::实例方法名, 这和静态方法引用类似, 区别不大
public class StudentComparator {
    public int compareStudentByScore(Student s1, Student s2) {
        return s1.getScore() - s2.getScore();
    }
    public int compareStudentByName(Student s1, Student s2) {
        return s1.getName().compareToIgnoreCase(s2.getName());
    }
}

@Test
public void Test2() {
        Student s1 = new Student("a", 10);
        Student s2 = new Student("b", 90);
        Student s3 = new Student("c", 50);
        Student s4 = new Student("d", 40);

        List<Student> students = Arrays.asList(s1, s2, s3, s4);
        // 传统lambda写法
        StudentComparator comparator = new StudentComparator();
        students.sort((x, y) -> comparator.compareStudentByScore(x, y));
        students.forEach(System.out::println);
        System.out.println("--------------");
        // 对象方法引用写法, 和静态的比较像, 对象和类的区别
        students.sort(comparator::compareStudentByScore);
        students.forEach(System.out::println);
        System.out.println("--------------");
}
3. 类名::实例方法名
@Data
@AllArgsConstructor
public class Student {
    private String name;
    private Integer score;

    public int compareByScore(Student student) {
        return this.getScore() - student.getScore();
    }

    public int compareByName(Student student) {
        return this.getName().compareToIgnoreCase(student.getName());
    }
}

/**
     类::实例方法 形式的方法引用
     这个方法依然是对象调用的, 用的是lambda表达式的第一个参数
     */
    @Test
public void Test3() {
        Student s1 = new Student("a", 10);
        Student s2 = new Student("b", 90);
        Student s3 = new Student("c", 50);
        Student s4 = new Student("d", 40);

        List<Student> students = Arrays.asList(s1, s2, s3, s4);

        students.sort(Student::compareByScore);
        students.forEach(System.out::println);

        System.out.println("-----------------------");
        // 加深理解
        List<String> cities = Arrays.asList("qingdao", "chongqing", "tianjin", "beijing");
        Collections.sort(cities, (c1, c2) -> c1.compareToIgnoreCase(c2));
        Collections.sort(cities, String::compareToIgnoreCase);
}

4. 构造方法引用: 类名::new
public String getString(Supplier<String> supplier) {
    return supplier.get() + "test";
}

public String getString2(String str, Function<String, String> function) {
    return function.apply(str);
}

/**
* 注意, 这里String::new两次调用的构造方法是不同的, 因为接口的需要不同
* 这个例子是说明 类名::new 这个方法引用会自动选择符合参数约定的方法来调用
*/
@Test
public void Test4() {
    MethodReferenceTest methodReferenceTest = new MethodReferenceTest();
    System.out.println(methodReferenceTest.getString(String::new));
 	System.out.println(methodReferenceTest.getString2("hello",String::new));
}
原文地址:https://www.cnblogs.com/Lothlorien/p/12023990.html