方法引用

2019-01-13  本文已影响5人  shz_Minato

一 定义

 方法引用就是通过方法的名字来指向某一个方法,类似于函数指针,其好处在于代码的简洁和去冗余。其基本结构如下:

类名::方法名

::是Java8的新操作符

 前面介绍过函数式接口的实例可以通过Lambda表达式和方法引用创建,下面通过案例介绍。

二 分类

 方法引用的类型有静态方法引用、类名实例方法引用、实例名实例方法引用和构造方法引用。

类型 形式
静态方法方法引用 ClassName :: staticMethod
类名实例方法引用 ClassName :: instanceMethod
实例名实例方法引用 InstanceName :: instanceMethod
构造方法引用 ClassName :: constructorMethod

三 实例介绍

静态方法引用
 注意点:方法的实参就是所对应的Lambda表达式的参数
 以泛型为Student类型的List排序为例

//实体类
public class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

}

//排序类
public class StudentComparator {

    //静态方法
    public static int sortByScore(Student student, Student student1) {
        return student.getScore()-(student1.getScore());
    }

    //静态方法
    public static int sortByName(Student student, Student student1) {
        return student.getName().compareTo(student1.getName());
    }
}

public class MethodReferenceTest {
    public static void main(String[] args) {
        Student student = new Student("zhangsan", 20);
        Student student1 = new Student("lisi", 30);
        Student student2 = new Student("wangwu", 10);
        Student student3 = new Student("maliu", 50);
        List<Student> studentList = Arrays.asList(student, student1, student2, student3);

        //匿名类的形式
        //sort是List接口的新增的默认方法,用于排序,排序的规则就是Comparator接口
        studentList.sort(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getScore()-o2.getScore();
            }
        });

        //Lambda表达式的形式
        //Comparator是函数式接口,其compare就是唯一的抽象方法,代表了比较的规则
        //因此Lambda表达式就是比较的规则-->该案例就是比较规则是score
        //Lambda表达式的类型是 (Student,Student)->{int}
        studentList.sort((item,item1)->item.getScore()-item1.getScore());

        //静态方法引用的形式  类名::静态方法
        //sortByScore方法与上述的Lambda表达式的类型一致:接受两个Student参数,返回一个int值
        //问题点在于:并未给sortByScore方法传入参数,因为编译器帮我们做了
        //参数就是Lambda表达式的参数列表
        studentList.sort(StudentComparator::sortByScore);
    }
}

类名实例方法引用
 注意点:Lambda表达式的第一参数是方法引用的调用者,之后的参数就是方法引用中的参数。
 以泛型为Student类型的List排序为例

public class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }


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

 
}


public class MethodReferenceTest {
    public static void main(String[] args) {
        Student student = new Student("zhangsan", 20);
        Student student1 = new Student("lisi", 30);
        Student student2 = new Student("wangwu", 10);
        Student student3 = new Student("maliu", 50);
        List<Student> studentList = Arrays.asList(student, student1, student2, student3);
        
        //匿名类的形式
        //sort是List接口的新增的默认方法,用于排序,排序的规则就是Comparator接口
        studentList.sort(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getScore()-o2.getScore();
            }
        });
        //Lambda表达式的形式
        //Lambda表达式的类型是(Student,Student)-{int}
        studentList.sort((item,item1)->item.compareByScore(item1));
        
        //类名实例方法引用的形式
        //问题在于:并未出现调用者和参数---->编译器帮我们做了
        //调用者就是上述Lambda表达式的第一个参数,
        //方法参数就是Lambda表达式中第一个参数之后的参数
        studentList.sort(Student::compareByScore);

    }
}

实例名实例方法引用
 注意点:方法引用的参数就是Lambda表达式的参数
 以泛型为Student类型的List遍历为例

public class MethodReferenceTest {
    public static void main(String[] args) {
        Student student = new Student("zhangsan", 20);
        Student student1 = new Student("lisi", 30);
        Student student2 = new Student("wangwu", 10);
        Student student3 = new Student("maliu", 50);
        List<Student> studentList = Arrays.asList(student, student1, student2, student3);


        //匿名类的形式
        //Consumer:接受一个参数,执行一个无结果的操作
        studentList.forEach(new Consumer<Student>() {
            @Override
            public void accept(Student student) {
                //控制台打印就是 接受一个student参数,执行一个无结果的操作
                System.out.println(student);
            }
        });

        //Lambda表达式的形式
        studentList.forEach(item -> System.out.println(item));

        //方法引用的形式
        //方法调用者就是System.out
        //问题在于:并未指出参数
        //参数是Lambda表达式的参数
        studentList.forEach(System.out::println);
        
    }
}

构造方法引用
 注意点:方法引用的参数就是Lambda表达式的参数

        //Supplier:不接受参数,返回一个值
        Supplier<String> supplier = String::new;//实际调用的是new String()方法
        
        //Function:接受一个参数,返回一个结果
        Function<String, String> function = item -> item;
        Function<String, String> function1 = String::new;//实际调用的是String(String original)
        Function<char[], String> function2 = String::new;//实际调用的是String(char value[])

四 小结

 ①方法引用本质是Lambda表达式的特殊化实现,其使用场景是Lambda表达式的的体只有一行代码,并且其实现已经有方法实现。
 ②一定要注意方法引用中调用者是谁,参数是谁。比如类名的实例方法引用,调用者是Lambda表达式的第一个参数,参数是Lambda表达式的第一个参数之后的参数

上一篇 下一篇

猜你喜欢

热点阅读