• Java 8 新特性 Ⅱ


    方法引用

    • 举例: Integer :: compare

    • 理解: 可以看作是基于lambda表达式的进一步简化

      • 当需要提供一个函数式接口的实例时, 可以使用lambda表达式提供实例

        • 当满足一定条件下, 可以使用方法引用or构造器引用替换lambda表达式
    • 实质: 方法引用作为函数式接口的实例 (注: 需要熟悉所使用函数式接口中的抽象方法)

    • 格式:

      • 类(或 对象) :: 方法名
    • 对象 :: 实例方法 (非静态方法)

      • 要求: 函数式接口的抽象方法a与其内部实现时调用的对象的某个方法b的形参列表和返回值类型一致
    • 类 :: 静态方法

      • 要求: 函数式接口的抽象方法a与其内部实现时调用的类的某个静态方法b的形参列表和返回值类型一致
    • 类 :: 实例方法

      • 要求: 函数式接口的抽象方法a与其内部实现时调用的对象的某个方法b的返回值类型相同。同时, 抽象方法a有 n个参数, 方法b中有n-1个参数, 且抽象方法a的第一个参数作为方法b的调用者, 且抽象方法a的后n-1个参数与 方法b的后n-1个参数的类型相同

    接下来的是代码的演示以及输出的结果

    1. 对象 :: 实例方法
    // 1. 对象 :: 实例方法
    @Test
    public void test1(){
        Consumer<String> con1 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con1.accept("hello1");
        System.out.println("===================");
        // 2. lambda表达式 (只有一个形参时, 小括号可以省)
        Consumer<String> con2 = s -> System.out.println(s);
        con2.accept("hello2");
        System.out.println("===================");
        // 3. 对象 :: 调用方法
        Consumer<String> con3 = System.out::println; // 只写方法名
        con3.accept("hello3");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行效果:

    对象::实例方法

    1. 类 :: 静态方法
    @Test
    public void test2(){
        // 1. 匿名函数
        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2); // 兼容 int, 并且这是静态方法, 所以用类来引用, 泛型只能存放包装类型 
            }
        };
        System.out.println(com1.compare(12, 23)); // 前面小, 输出 -1
        System.out.println("=========================");
        // 2. lambda
        Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1, o2);
        System.out.println(com2.compare(23,21));
        System.out.println("=========================");
        // 3. 引用函数
        Comparator<Integer> com3 = Integer :: compare;
        System.out.println(com3.compare(23,11));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行效果:

    类::静态方法

    1. 类 :: 实例方法
    // 3. 类 :: 实例方法
    @Test
    public void test3(){
        // 1.
        Comparator<String> com1 = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2); // 形参列表不一样, 返回值一样 1个参数调用 n-1为被调用的参数
            }
        };
        System.out.println(com1.compare("abc","cdf"));
        System.out.println("========================");
        // 2. lambda表达式
        Comparator<String> com2 = (o1, o2) -> o1.compareTo(o2); // 只是表达式有所差异, 执行速度一样
        System.out.println(com2.compare("abb","abb"));
        System.out.println("=====================");
        // 3. 方法引用
        Comparator<String> com3 = String::compareTo; // 返回值的类 :: 实例方法
        System.out.println(com3.compare("ssa","aac")); // 第一个参数小, 返回负数; 相等 返回0; 第一个数大, 返回正数
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    运行效果:

    输出结果

    构造器引用

    可以看作是特殊的方法

    • 格式: 类名 :: new

    • 说明

      • 调用类名对应的类中的某一个确定的构造器
      • 调用哪一个构造器? 取决于函数式接口的抽象对象的形参列表
    // 构造器引用
    @Test
    public void test1(){
        //1.
        Supplier<Employee> sup1 = new Supplier<Employee>() {
            @Override
            public Employee get() {
                return new Employee(); // 构造器, 创建对象
            }
        };
        System.out.println(sup1.get()); // 会调用无参构造
        // 2. 方法引用
        Supplier<Employee> sup2 = Employee :: new;
        System.out.println(sup2.get());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Employee.java 就是拥有 age, id, name, salary属性以及构造器 setter, getter, toString方法的文件

    运行效果:

    运行结果

    数组引用

    • 格式: 数组名[] :: new
    @Test
    public void test2(){
        Function<Integer, Employee[]> func1 = new Function<Integer, Employee[]>() {
            @Override
            public Employee[] apply(Integer length) {
                return new Employee[length];
            }
        };
        System.out.println("============");
        // 2. 数组引用
        Function<Integer, Employee[]> fun2 = Employee[] :: new;
        System.out.println(fun2.apply(100).length);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行效果:

    输出结果

  • 相关阅读:
    水电站10kV厂用电保护装置改造
    Tensorflow—第四讲网络八股扩展
    C#实现的下拉多选框,下拉多选树,多级节点
    700. 二叉搜索树中的搜索
    c++征途 --- 类和对象 --- 对象特性(下)
    VMware Workstation Player虚拟机Ubuntu启用Windows共享目录
    什么是对象的原型?
    读写分离技术架构图
    Docker 自动化部署(保姆级教程)
    【 Java架构师-技术专家 】慕课2、springboot基础回顾
  • 原文地址:https://blog.csdn.net/weixin_46388660/article/details/133970311