• JDK8--05:方法引用和构造器引用


    在上一篇文章中,说过JDK8中内置的函数时接口,为了方便使用,JDK8还提供了方法引用和构造器引用,来简化lambda的写法

    1、方法引用

    方法引用说明:lambda表达式中的方法已经在其他方法中已经有实现,可以直接使用双冒号进行方法引用,引用的前提是使用的出入参和引用方法的出入参必须一致

    对象引用有三种写法:

      对象::实例方法名

      类::静态方法名

      类::实例方法名

    再写代码示例前,先新增一个Student的内部类,以供后面演示使用

    class Student{
            private String name = "lcl";
            private Integer age = 18;
    
            public String getName() {
                return name;
            }
    
            public Integer getAge() {
                return age;
            }
    
        }

    (1)首先说第一种,对象::实例方法名

    @Test
    public void test1(){
    //方法引用,lambda表达式中的方法已经在其他方法中已经有实现,可以直接使用双冒号进行方法引用,引用的前提是使用的出入参和引用方法的出入参必须一致
    //对象::实例方法名
    PrintStream ps = System.out;
    Consumer<String> consumer = (x)->ps.println(x);
    consumer.accept("000000000000000000000");

    PrintStream ps1 = System.out;
    Consumer<String> consumer1 = ps1::println;
    consumer1.accept("111111111111111111111");

    Consumer<String> consumer2 = System.out::println;
    consumer2.accept("2222222222222222222222");

    }

    上述代码中,第一种实现,就是使用原来说的lambda的写法,因为在PrintStream对象中,已经有println方法的实现,并且println方法的出入参(入参可以是String,出参为空)符合消费型接口Consumer的出入参,因此可以直接使用方法引用返回Consumer。

    测试结果:

     同样,我们可以使用自己创建的类,只要方法的出入参符合函数时接口的出入参即可,这里拿上面创建的Student对象的getName和getAge方法演示

        @Test
        public void test4(){
    
            Student student = new Student();
            Supplier<String> supplier = ()-> student.getName();
            log.info("Supplier===================={}",supplier.get());
    
            Supplier<Integer> supplier1 = student::getAge;
            Integer age = supplier1.get();
            log.info("Supplier===================={}",age);
        }

    由于getAge和getName方法的出入参都符合Suppiler的出入参(无入参,有出参),因此可以使用Suppiler进行处理

    测试结果:

    (2)然后再说第二种实现方式    类::静态方法名

        @Test
        public void test5(){
            //类::静态方法名
            Comparator<Integer> comparator = Integer::compare;
            log.info("=================={}",comparator.compare(10,20));
        }

    测试结果:

     (3)最后说第三种实现方式      类::实例方法名

    使用该种方法,有条件限制:第一个入参是调用该方法的调用者,第二个参数是方法引用的入参时,可以使用类的实例方法调用

    示例代码:

        @Test
        public void test6(){
            //类::实例方法名
            //条件限制:第一个入参是调用该方法的调用者,第二个参数是方法引用的入参时,可以使用类的实例方法调用
            BiPredicate<String, String> biPredicate = (x, y) -> x.equals(y);
            log.info("=========================={}",biPredicate.test("111","111"));
    
            BiPredicate<String, String> biPredicate1 = String::equals;
            log.info("=========================={}",biPredicate.test("111","222"));
    
        }

    测试结果:

    2、构造器引用

    首先为Student创建三个构造器,分别是无参构造器,一个参数的构造器和两个参数的构造器

    class Student{
            private String name = "lcl";
            private Integer age = 18;
    
            public String getName() {
                return name;
            }
    
            public Integer getAge() {
                return age;
            }
    
            public Student(String name){
                this.name = name;
                age = 15;
            }
    
            public Student(String name, Integer age){
                this.name = name;
                this.age = age;
            }
    
            public Student(){
                this.name = "lcl";
                this.age = 15;
            }
    
        }

    然后,演示构造器引用的使用方法:

        @Test
        public void test2(){
            Supplier<Student> supplier = ()->new Student();
            log.info("======================{}",JSON.toJSONString(supplier.get()));
            Supplier<Student> supplier1 = Student::new;
            log.info("======================{}",JSON.toJSONString(supplier1.get()));
    
            Function<String, Student> function = (x)->new Student(x);
            log.info("===================={}",JSON.toJSONString(function.apply("lcl")));
            
            Function<String, Student> function1 = Student::new;
            log.info("===================={}",JSON.toJSONString(function1.apply("mm")));
            BiFunction<String , Integer ,Student> function2 = Student::new;
            log.info("===================={}",JSON.toJSONString(function2.apply("xxx",25)));
        }

    代码分为三组,分别演示对于无参构造器,一个参数的构造器和两个参数的构造器的引用,可以发现,引用的写法一摸一样,具体调用的是哪个构造器,则根据函数式接口的参数而定。

    测试结果:

     4、除了方法引用和构造器引用外,JDK8还提供了数组引用,其实也相当于是构造器引用

    代码示例:

        @Test
        public void test3(){
            //数组引用
            Function<Integer,String[]> function = (x)-> new String[x];
            log.info("===================={}",function.apply(10).length);
    
            Function<Integer,String[]> function1 = String[]::new;
            log.info("===================={}",function1.apply(5).length);
        }

    测试结果:

  • 相关阅读:
    Chrome下载无后缀问题
    duilib程序HelloWorld
    go的windows下的安装包
    ASP.NET MVC异步上传图片和富文本编辑器的使用详解
    搭建go环境(windows和linux)
    构建离线Go编程指南——gotour
    判定模块加载时是否存在循环依赖
    Winform开发框架之框架演化
    为什么要写技术博
    JTREE使用例子—创建一个客户端界面
  • 原文地址:https://www.cnblogs.com/liconglong/p/12976309.html
Copyright © 2020-2023  润新知