• 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的另一种表现形式
    • 方法引用被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致
    • 方法引用中使用类::实例方法的条件是第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数
    • 构造器引用需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表一致
  • 相关阅读:
    【BZOJ 3732】 Network
    【BJOI 2018】 求和
    【HDU 1005】 Number Sequence
    【HDU 3652】 B-numbers
    【SCOI 2007】 降雨量
    BZOJ2186 SDOI2008沙拉公主的困惑(数论)
    #38 游戏(线段树)
    BZOJ2339 HNOI2011卡农(动态规划+组合数学)
    BZOJ3107 CQOI2013二进制A+B(动态规划)
    BZOJ3083 遥远的国度(树链剖分+线段树)
  • 原文地址:https://www.cnblogs.com/zhixie/p/13297141.html
Copyright © 2020-2023  润新知