Java 8 方法引用

555 阅读2分钟

简介

  • 方法引用是Lambda的特殊实现,所以只有函数式接口可以引用方法

  • 它只是一个语法糖,对语言本身没有太大意义

  • 总之,就是借用已经存在的方法,无需再手动写Lambda表达式了

  • 它有四种引用方式

1、静态方法引用

顾名思义就是引用静态的方法

  • 格式 类名::静态方法名

样例,根据不同的属性给对象排序

  • 创建一个Student类
public class Student {
    String name;
    int score;
    public static int compareByScore(Student stu1,Student stu2){//静态方法1
        return stu1.getScore()-stu2.getScore();
    }
    public static int compareByName(Student stu1,Student stu2){//静态方法
        return stu2.getName().compareTo(stu1.getName());//会倒序
    }
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
   //getter和setter方法。。。
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}
  • 测试
public class Test {
    public static void main(String[] args) {
        Student student = new Student("张三",78);
        Student student2 = new Student("李四",90);
        Student student3 = new Student("王五",50);
        Student student4 = new Student("赵六",77);
        Student student5 = new Student("钱七",100);
        List<Student> studentList = Arrays.asList(student,student2,student3,student4,student5);
        //studentList.sort((s1,s2) -> s1.getScore() - s2.score); //正常的Lambda,以score排序
        //集合自带sort(函数式接口Comparator<T>),需要实现的是int compare(T o1, T o2);方法
        studentList.sort(Student::compareByScore);//因为Student类中已经有实现了,直接引用
        studentList.forEach(s -> System.out.println(s));//打印
        System.out.println("----------------");
        studentList.sort(Student::compareByName);
        studentList.forEach(s -> System.out.println(s));
    }
}

image.png

2、实例方法引用

  • 格式 引用名(对象名)::实例方法名

样例,前一个样例的变体

  • 新创建一个有compare方法的类,方法不再是静态
public class StudentComparetor {
    public int compareByScore(Student stu1,Student stu2){//非静态,按分数正序
        return stu1.getScore()-stu2.getScore();
    }
    public int compareByName(Student stu1,Student stu2){//非静态,按名字倒序
        return stu2.getName().compareTo(stu1.getName());
    }
}

测试

public class Test {
    public static void main(String[] args) {
        StudentComparetor comparetor = new StudentComparetor();//实例化刚创建的类StudentComparetor
        Student student = new Student("张三",78);
        Student student2 = new Student("李四",90);
        Student student3 = new Student("王五",50);
        Student student4 = new Student("赵六",77);
        Student student5 = new Student("钱七",100);
        List<Student> studentList = Arrays.asList(student,student2,student3,student4,student5);
        //studentList.sort((s1,s2) -> s1.getScore() - s2.score);//正常的lambda表达式
        studentList.sort(comparetor::compareByScore);//引用了对象comparetor的方法
        studentList.forEach(s -> System.out.println(s));
        System.out.println("----------------");
        studentList.sort(comparetor::compareByName);
        studentList.forEach(s -> System.out.println(s));
    }
}

结果同上

3、实例方法引用2.0

  • 格式 类名::方法名

样例,在前面的Student类中compareByScore方法改了

 public int compareByScore(Student stu){  //参数只有一个
        return this.getScore()-stu.getScore();//当前对象调用,使用一个参数
 }

测试,依旧是排序

studentList.sort((s , s1) ->s.compareByScore(s1));
studentList.sort(Student::compareByScore);//和上面lambda表达式是等价的

4、构造方法引用

构造方法的返回值是对象

测试

public class Test {
    public String getString(Supplier<String> supplier){
        return supplier.get()+"getString from No-parameter construction";
    }
    public String getString2(String str,Function<String, String> function){
        return function.apply(str);
    }
    public static void main(String[] args) {
        Test test = new Test();
        //使用String的无参构造实现supplier.get(),因为get的返回值是String
        System.out.println(test.getString(String::new));
        //使用String的有参构造,返回String,因为function.apply(str);参数和返回值与String的有参构造一致
        System.out.println(test.getString2("hello world",String::new));
}