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的另一种表现形式
    • 方法引用被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致
    • 方法引用中使用类::实例方法的条件是第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数
    • 构造器引用需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表一致
  • 相关阅读:
    java程序员必读的书籍(适合于本人)
    面试第三天
    sql常用的函数(持续更新中)
    linux 常用命令
    drf的Response返回字符串有问题
    celery pip仓库上的代码有问题 请使用git上最新版
    PyCrypto已放弃维护 请使用PyCryptodome
    django+celery实现异步任务
    利用Oh-My-Zsh打造你的超级终端---待排版
    pycharm搭配docker本地调试
  • 原文地址:https://www.cnblogs.com/zhixie/p/13297141.html
Copyright © 2011-2022 走看看