• Java8新特性之方法引用


    一、概述

    1. 引入

    方法引用是在Java8中引入的新特性,使用方法引用可以进一步的简化Lambda的一些基本操作。我们知道在JavaScript中方法也是对象,也就是说,我们可以直接对方法进行传递,方法可以作为某个函数的参数。Java的方法引用也是类似的思想,使用方法引用可以对方法的引用进行传递,然后由接受的方法底层进行执行。

    方法引用使用的一般方式如下:

    List<String> list = Arrays.asList("A","B","C");
    list.forEach(System.out::println);
    

    在使用Lambda表达式时我们一般这样使用:

    list.forEach((e) -> System.out.println(e));
    

    在使用匿名内部类时,我们通常这样使用:

    list.forEach(new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    });
    

    2. 总结

    根据上面引入部分的内容我们可以看出,方法引用比Lambda表达式使用起来更为方便,当时并不是所有的场景都适合使用方法引用。想要使用方法引用需要符合以下条件:

    引用的方法的参数和返回值类型和Lambda表达式使用的函数式接口中的抽象方法的参数和返回值相同。
    

    我们可以分析一下上面的例子:

    list.forEach(System.out::println);
    //System.out表示的是一个对象,而println是其中的一个实例方法。在这里表示引用System.out对象中的println方法
    //而println方法有一个参数,类型是String,没有返回值
    
    new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    }
    //上述内容表示一个消费型的函数式接口,它里面有一个抽象方法,accept,有一个参数,类型为String
    //没有返回值
    

    可以看出,在使用方法引用方式时println方法的参数类型数量以及返回值类型和函数式接口Consumer中的accept方法的参数类型数量和返回值类型都是一样的。所以在这里可以使用方法引用。

    二、构造方法引用

    1. 使用

    在接口新特性中,我们讲到,Java8中的函数式接口有一种供给型接口Supplier。我们可以使用这个接口来完成创建对象的过程。

    Supplier<Object> supplier1 = new Supplier<Object>() {
        @Override
        public Object get() {
            return new Object();
        }
    };
    

    但是这个过程很复杂,后来我们可以使用Lambda表达式来完成这个过程。

    Supplier<Object> supplier2 = () -> new Object();
    

    使用方法引用之后,我们可以直接这样写

    Supplier<Object> supplier3 = Object::new;
    System.out.println(supplier3.get());
    

    2. 注意

    通过上面的案例我们需要再次明确:

    方法引用的使用是在被引用的方法参数,返回值信息和函数式接口中抽象方法的参数,返回值等信息相同的情况下使用

    比如说在使用构造方法引用时如果没有无参构造器,就没办法使用Supplier接口来实现方法引用。

    三、类方法(静态方法)引用

    1. 使用

    在接口新特性中我们讲到Java8中有一个函数式接口是函数式Function,我们通过这个接口可以完成很多的事情。

    例如,将String类型的字符串转换为Int类型

    Function<String,Integer> function2 = new Function<String, Integer>() {
        @Override
        public Integer apply(String s) {
            return Integer.parseInt(s);
        }
    };
    

    同时我们还可以使用Lambda表达式的方式

    Function<String,Integer> function = (s) -> Integer.parseInt(s);
    

    使用方法引用的方式

    Function<String,Integer> function1 = Integer::parseInt;
    

    还有就是比较两个Integer类型的值的大小

    传统的方式

    Comparator<Integer> comparator = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return Integer.compare(o1, o2);
        }
    };
    

    Lambda表达式方式

    Comparator<Integer> comparator1 = ((o1, o2) -> Integer.compare(o1, o2));
    

    方法引用方式

    Comparator<Integer> comparator2 = Integer::compareTo;
    

    四、类实例方法引用

    1. 案例

    对字符串数组中的元素进行排序。

    传统方式

    Arrays.sort(strings, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    });
    

    Lambda表达式方式

    Arrays.sort(strings,(a,b) -> a.compareTo(b));
    

    方法引用方式

    Arrays.sort(strings,String::compareTo);
    

    五、对象实例方法引用

    1. 案例

    统计List集合的容量

    传统方式

    List<String> list = Arrays.asList("1","2","3");
    Supplier<Integer> supplier = new Supplier<Integer>() {
        @Override
        public Integer get() {
            return list.size();
        }
    };
    

    Lambda表达式

    Supplier<Integer> supplier1 = () -> list.size();
    

    对象实例方法引用

    Supplier<Integer> supplier2 = list::size;
    

    如果不使用对象实例方法方式,也可以这样

    //Lambda表达式
    Function<List<?>,Integer> function = (e) -> e.size();
    //方法引用方式
    function = List::size;
    
  • 相关阅读:
    合并字符串中的多个空格
    IfcSpecularRoughness
    IfcSpecularExponent
    IfcPresentableText
    IfcFontWeight
    IfcFontVariant
    uwb ifc模型定位測試
    IfcFontStyle
    IfcGeometricModelResource
    qt6安装
  • 原文地址:https://www.cnblogs.com/zwscode/p/14284080.html
Copyright © 2020-2023  润新知