Java8新特性-005-方法引用

  • lambda表达式的语法糖,一种特殊情况,让代码更加简洁
  • 入门案例
    public class MethodDemo {
    
        public static void main(String[] args) {
            List<String> list = Arrays.asList("hello","world","hello world");
            //传统写法
            list.forEach(item -> System.out.println(item));
            
            //方法引用
            list.forEach(System.out::println);
        }
    }
    

概念

  • 方法引用可以看成是一个函数指针,将参数执行到函数指针指向函数的地方执行

四类

类名::静态方法名
  • 对student类进行排序实现
    public class MethodDemo1{
    
    
        public static void main(String[] args) {
    
            List<Student> students =
                    Arrays.asList(new Student().setName("zhangsan").setAge(10),
                            new Student().setName("lisi").setAge(2),
                            new Student().setName("wangwu").setAge(3),
                            new Student().setName("zhaoliu").setAge(1));
    
            //之前的写法
            students.sort((s1,s2)->Student.sortByAge(s1,s2));
            System.out.println(students);
    
            //方法引用之后的写法,相当于Comparator内部的compare方法
            //然后执行函数指针指向的方法,Student.sortByAge方法来使用
            students.sort(Student::sortByAge);
            System.out.println(students);
    
        }
    
    
        @Data
        @ToString
        @Accessors(chain = true)
        static class Student{
            private String name;
            private int age;
    
    
            public static int sortByAge(Student student,Student student2){
                return student.age - student2.age;
            }
        }
    }
    
  • 理解:条件参数相同,之前写法中调用了Comparator的compare方法,内部是两个参数,同时sortByAge也是两个入参,同时返回也是一样的,在调用Comparator的compare方法时,内部调用了函数指针,指向了Student.sortByAge静态方法,将入参传递进去,进而计算出结果。
  • 入参和返回参数的类型都是相同的,可以认为是传统写法的另外一种写法,一种语法糖。
  • class::staticMethod class.staticMethod区别
    • class::staticMethod是方法引用的一种写法类型,由编译器自动传入参数,不可以填写参数,而class.staticMethod是调用静态方法需要传递参数
    • class::staticMethod表示指向此方法的一种形式,而class.staticMethod是函数调用,后面必须跟上括号之类的,不可以单独存在。
引用名(对象名)::实例方法名
  • 对Student进行排序
  • 代码
    public class MethodDemo2 {
    
    
        public static void main(String[] args) {
    
            List<Student> students =
                    Arrays.asList(new Student().setName("zhangsan").setAge(10),
                            new Student().setName("lisi").setAge(2),
                            new Student().setName("wangwu").setAge(3),
                            new Student().setName("zhaoliu").setAge(1));
    
            StudentComparator comparator = new StudentComparator();
    
    
            //对象名::实例方法  的方法引用形式
            students.sort(comparator::sortByAge);
            System.out.println(students);
    
    
        }
    
    
        @Data
        @ToString
        @Accessors(chain = true)
        static class Student{
            private String name;
            private int age;
    
        }
    
    
    
        static class StudentComparator{
            public int sortByAge(Student student,Student student2){
                return student.age - student2.age;
            }
        }
    }
    
  • 理解:和前面的类::静态方法一样,请求参数会由编译器自动传递,请求参数和返回参数必须相等,同样的,该形式也是一个函数指针,指向了要执行的方法,与上面不同的是,此方法是属于某个实例的,而不是类的。
类名::实例方法名
  • 对Student进行排序
  • 代码
    public class MethodDemo3 {
    
    
        public static void main(String[] args) {
    
            List<Student> students =
                    Arrays.asList(new Student().setName("zhangsan").setAge(10),
                            new Student().setName("lisi").setAge(2),
                            new Student().setName("wangwu").setAge(3),
                            new Student().setName("zhaoliu").setAge(1));
    
    
            students.sort(Student::sortByAge);
            System.out.println(students);
    
        }
    
    
        @Data
        @ToString
        @Accessors(chain = true)
        static class Student{
            private String name;
            private int age;
    
            public int sortByAge(Student student) {
                return this.age - student.age;
            }
    
        }
    
    }
    
  • 疑问点
    • 属于实例的方法,为何可以使用Student::sortByAge?
      • sortByAge属于对象的方法,所以肯定是存在一个对象调用的,那么这个对象是谁?就是sort中lambda表达式的第一个参数调用的,那么内部是如何进行的呢,对于lambda表达式而言,第一个参数调用后面的方法(sortByAge),其他的参数将作为后面方法的入参传递进去进行执行。
    • sort接收的入参是两个参数,为何现在是一个参数,因为sortByAge的输入还是输出都是一个参数,是如何调用的?
类名::new 构造方法引用
  • 实质是调用构造方法,生成对象
  • 代码
    public class MethodDemo5 {
    
    
        public String printString(Supplier<String> supplier){
            return supplier.get()+"test";
        }
    
    
        public String printString(String str , Function<String,String> function){
            return function.apply(str);
        }
    
    
        public static void main(String[] args) {
    
    
            MethodDemo5 demo5 = new MethodDemo5();
    
            //调用new String()构造方法
            System.out.println(demo5.printString(String::new));
    
            //调用new String(str)构造方法
            System.out.println(demo5.printString("print",String::new));
    
        }
    }
    
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页