JDK1.8学习笔记4-方法引用

方法引用—Method ReferenceLambda表达式的语法糖

  • 示例
public class MethodReferenceTest {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("hello", "world", "hello world");    
        list.forEach(System.out ::  println);        
    }
}

执行结果

hello
world
hello world

我们可以将方法引用看着是一个函数指针Function Pointer

1.方法引用的分类

方法引用分为四类

  • 静态方法引用—类名::静态方法名
  • 示例方法引用引用名(对象名)::实例方法名
  • 类方法引用—类名::实例方法名
  • 构造方法引用—类名::new

1.1 静态方法引用—类名::静态方法名(className::staticMethod)

其所使用的Lambda表达式恰好有一个静态方法完成与之相同的事情,则可将其替换为方法引用

  • 实例
	public class MethodReferenceTest {


    public static void main(String[] args) {

       Student student1 = new Student("zhangsan", 20);
       Student student2 = new Student("lisi", 90);
       Student student3 = new Student("wanwu", 30);
       Student student4 = new Student("zhaoliu", 60);


       List<Student> students = new ArrayList<>();
        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);

        //使用lambda表达式
        //通过成绩降序排序
        students.sort((studentParam1, studentParam2)
                -> Student.compareStudentByScore(studentParam2, studentParam1));
        students.forEach(student -> System.out.println(student.getScore()));
        System.out.println("+++++++");

        //通过名字降序排序
        students.sort((studentParam1, studentParam2)
                -> Student.compareByScoreByName(studentParam2, studentParam1));
        students.forEach(student -> System.out.println(student.getName()));
        System.out.println("+++++++");


        //使用方法引用
        //通过成绩升序排序
        students.sort(Student :: compareStudentByScore);
        students.forEach(student -> System.out.println(student.getScore()));
        System.out.println("+++++++");

        //通过名字升序排序
        students.sort(Student :: compareByScoreByName);
        students.forEach(student -> System.out.println(student.getName()));

        System.out.println("+++++++");

    }
}
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 static int compareStudentByScore(Student student1, Student student2){
        return student1.getScore()-student2.getScore();
    }

    public static int compareByScoreByName(Student student1, Student student2){
        return student1.getName().compareToIgnoreCase(student2.getName());
    }
}

执行结果

90
60
30
20
+++++++
zhaoliu
zhangsan
wanwu
lisi
+++++++
20
30
60
90
+++++++
lisi
wanwu
zhangsan
zhaoliu
+++++++

注意事项
虽然方法引用className::staticMethodclassName.staticMethod执行的结果是一致的.但可以认为两者是没有任何关系

  • 前者是方法引用的一种表达式形式,是函数指针,不能传递任何参数
  • 后者不能作为单独的表达式存在,需要传递参数,表示方法调用

1.2 实例方法引用—引用名(对象名)::实例方法名

  • 示例
public class MethodReferenceTest {


    public static void main(String[] args) {
       Student student1 = new Student("zhangsan", 20);
       Student student2 = new Student("lisi", 90);
       Student student3 = new Student("wanwu", 30);
       Student student4 = new Student("zhaoliu", 60);


       List<Student> students = new ArrayList<>();
        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);


        StudentComparator comparator = new StudentComparator();

        students.sort(comparator :: compareByScoreByName);

        students.forEach(student -> System.out.println(student.getName()));

        System.out.println("++++++++");

        students.sort(comparator :: compareStudentByScore);
        students.forEach(student -> System.out.println(student.getScore()));
    }
}
public class StudentComparator {
    public int compareStudentByScore(Student student1, Student student2){
        return student1.getScore()-student2.getScore();
    }

    public int compareByScoreByName(Student student1, Student student2){
        return student1.getName().compareToIgnoreCase(student2.getName());
    }
}

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;
    }
}

执行结果

isi
wanwu
zhangsan
zhaoliu
++++++++
20
30
60
90


1.3 类方法引用—类名::实例方法名

  • 实例
public class MethodReferenceTest {

    public static void main(String[] args) {

       Student student1 = new Student("zhangsan", 20);
       Student student2 = new Student("lisi", 90);
       Student student3 = new Student("wanwu", 30);
       Student student4 = new Student("zhaoliu", 60);

       List<Student> students = new ArrayList<>();
        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);

        students.sort(Student :: compareBySore);
        students.forEach(student -> System.out.println(student.getScore()));

        System.out.println("+++++++");

        students.sort(Student::compareByName);
        students.forEach(student -> System.out.println(student.getName()));
    }
}
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 compareBySore(Student student){
        return this.score - student.getScore();
    }

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

}

执行结果

20
30
60
90
+++++++
lisi
wanwu
zhangsan
zhaoliu

对于类方法引用存在一个疑问:
查看Comparator函数接口源码可知,其接口int compare(T o1, T o2)需传递两个参数
StudentcompareBySorecompareByName方法只接收一个参数
students.sort(Student :: compareBySore)students.sort(Student::compareByName)是如何执行成功的呢?
我的猜测是答案就在Student对象对应的字节码文件Student.class中,通过jclasslib查看两方法的LocalVaralbleTable可知
方法compareBySore的局部变量信息
方法compareByName的局部变量信息
StudentcompareBySorecompareByName方法的其实有两个参数,第一个是this,第二个才是我们实际的传参student
那这样就能说通了

但查看String对象对应的class文件,则跟上述猜测不一致,如下示例

  • 示例
public class MethodReferenceTest {

    public static void main(String[] args) {

        List<String> cities = Arrays.asList("guangzhoug", "beijing", "chongqing", "shanghai");

        Collections.sort(cities, String :: compareToIgnoreCase);

        cities.forEach(city -> System.out.println(city));
    }
}

执行结果

beijing
chongqing
guangzhoug
shanghai

通过jclasslib查看String.classcompareToIgnoreCase方法的LocalVaralbleTable可知,可惜compareToIgnoreCase方法只有LineNumberTable,没有LocalVaralbleTable
方法compareToIgnoreCase的Code属性信息


1.4 构造方法引用—类名::new

  • 示例
public class MethodReferenceTest {
    public String getString1(Supplier<String> supplier){
        return supplier.get() + "test";
    }

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

    public static void main(String[] args) {
        MethodReferenceTest test = new MethodReferenceTest();
        System.out.println(test.getString1(String :: new));

        System.out.println(test.getString2("hello", String :: new));
    }
}

执行结果

test
hello

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值