zoukankan      html  css  js  c++  java
  • Java8——方法引用

    方法引用就是通过类名或方法名引用已经存在的方法来简化lambda表达式。那么什么时候需要用方法引用呢?如果lamdba体中的内容已经有方法实现了,我们就可以使用方法引用。

    一、方法引用的三种语法格式

    1. 对象::实例方法名

    lamdba写法:

    @Test
    void test1(){
        Consumer<String> con = x -> System.out.println(x);
    }
    

    方法引用写法:

    @Test
    void test2(){
        PrintStream out = System.out;
        Consumer<String> con = out::println;
    }
    

    consumer接口:

    @FunctionalInterface
    public interface Consumer<T> {
        void accept(T t);
    }
    

    注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。

    2. 类::静态方法名

    lamdba写法:

    @Test
    void test3(){
        Comparator<Integer> com = (x, y) -> Integer.compare(x,y);
    }
    

    方法引用写法:

    @Test
    void test4(){
        Comparator<Integer> com = Integer::compare;
    }
    

    Comparator接口:

    @FunctionalInterface
    public interface Comparator<T> {
        int compare(T o1, T o2);
    }
    

    Integer类部分内容:

    public final class Integer extends Number implements Comparable<Integer> { 
    	public static int compare(int x, int y) {
            return (x < y) ? -1 : ((x == y) ? 0 : 1);
        }
    }
    

    注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。

    3. 类::实例方法名

    lamdba写法:

    @Test
    void test5(){
    
        BiPredicate<String,String> bp = (x,y) -> x.equals(y);
    }
    

    方法引用写法:

    @Test
    void test6(){
        BiPredicate<String,String> bp = String::equals;
    }
    

    BiPredicate接口:

    @FunctionalInterface
    public interface BiPredicate<T, U> {
        boolean test(T t, U u);
    }
    

    注意:第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数时,就可以使用这种语法。

    二、构造器引用

    类::new

    lamdba写法:

    @Test
    void test7(){
        Supplier<Person> supplier = ()->new Person();
    }
    

    构造器引用写法:

    @Test
    void test8(){
        Supplier<Person> supplier = Person::new;
    }
    

    Supplier接口:

    @FunctionalInterface
    public interface Supplier<T> {
        T get();
    }
    

    Person类:

    @Data
    public class Person implements Serializable {
        private static final long serialVersionUID = -7008474395345458049L;
    
        private String name;
        private int age;
    
        public Person() {
        }
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    

    注意:person类中有两个构造器,要调用哪个构造器是函数式接口决定的,也就是Supplier接口中的get()方法是无参的,那么就调用的是person中的无参构造器。

    三、数组引用

    Type::new

    lamdba写法:

    @Test
    void test9(){
        Function<Integer,String[]> fun = x -> new String[x];
    }
    

    数组引用写法:

    @Test
    void test10(){
        Function<Integer, String[]> fun = String[]::new;
    }
    

    Function接口部分内容:

    @FunctionalInterface
    public interface Function<T, R> {
        R apply(T t);
    }
    

    总结

    • 方法应用及构造器引用其实可以理解为lamdba的另一种表现形式
    • 方法引用被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致
    • 方法引用中使用类::实例方法的条件是第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数
    • 构造器引用需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表一致
  • 相关阅读:
    vue-route+webpack部署单页路由项目,访问刷新出现404问题
    linux下安装大于2T硬盘,并分区替换现有mysql数据目录挂载点实现扩容
    linux下将mbr分区转换为gpt分区
    [go]接口型函数分析
    Type-C协议简介(CC检测原理)
    RocketMQ 重试机制
    RocketMQ与Kafka对比-评价版
    分布式开放消息系统(RocketMQ)的原理与实践
    mysql8.0的RPM方式安装
    nacos集群配置笔记
  • 原文地址:https://www.cnblogs.com/zhixie/p/13297141.html
Copyright © 2011-2022 走看看