天天看點

《JDK8新特性專題》-04方法引用

文章目錄

  • ​​1.為什麼要用方法引用​​
  • ​​1.1.lambda表達式備援​​
  • ​​1.2.解決方案​​
  • ​​2.方法引用的格式​​
  • ​​2.1.對象名::方法名​​
  • ​​2.2.類名::靜态方法名​​
  • ​​2.3 類名::引用執行個體方法​​
  • ​​2.4.類名::構造器​​
  • ​​2.5 數組::構造器​​

1.為什麼要用方法引用

1.1.lambda表達式備援

在使用​

​Lambda​

​​表達式的時候,也會出現代碼備援的情況,比如:用​

​Lambda​

​表達式求一個數組的和

import java.util.function.Consumer;

public class FunctionRefTest01 {

    public static void main(String[] args) {
        printMax(a->{
            // Lambda表達式中的代碼和 getTotal中的代碼備援了
            int sum = 0;
            for (int i : a) {
                sum += i;
            }
            System.out.println("數組之和:" + sum);
        });
    }

    /**
     * 求數組中的所有元素的和
     * @param a
     */
    public void getTotal(int a[]){
        int sum = 0;
        for (int i : a) {
            sum += i;
        }
        System.out.println("數組之和:" + sum);
    }

    private static void printMax(Consumer<int[]> consumer){
        int[] a= {10,20,30,40,50,60};
        consumer.accept(a);
    }
}      

1.2.解決方案

因為在​

​Lambda​

​表達式中要執行的代碼和我們另一個方法中的代碼是一樣的,這時就沒有必要重寫一份邏輯了,這時我們就可以“引用”重複代碼

public class FunctionRefTest02 {

    public static void main(String[] args) {
        // :: 方法引用 也是JDK8中的新的文法
        printMax(FunctionRefTest02::getTotal);
    }

    /**
     * 求數組中的所有元素的和
     * @param a
     */
    public static void getTotal(int a[]){
        int sum = 0;
        for (int i : a) {
            sum += i;
        }
        System.out.println("數組之和:" + sum);
    }

    private static void printMax(Consumer<int[]> consumer){
        int[] a= {10,20,30,40,50,60};
        consumer.accept(a);
    }
}      
:: 方法引用 也是JDK8中的新的文法

2.方法引用的格式

符号表示:::      

符号說明:雙冒号為方法引用運算符,而它所在的表達式被稱為​

​方法引用​

應用場景:如果Lambda表達式所要實作的方案,已經有其他方法存在相同的方案,那麼則可以使用方法引用。

常見的引用方式:

方法引用在JDK8中使用是相當靈活的,有以下幾種形式:

  1. instanceName::methodName 對象::方法名
  2. ClassName::staticMethodName 類名::靜态方法
  3. ClassName::methodName 類名::普通方法
  4. ClassName::new 類名::new 調用的構造器
  5. TypeName[]::new String[]::new 調用數組的構造器

2.1.對象名::方法名

這是最常見的一種用法。如果一個類中的已經存在了一個成員方法,則可以通過對象名引用成員方法

public static void main(String[] args) {
    Date now = new Date();
    Supplier<Long> supplier = ()->{return now.getTime();};
    System.out.println(supplier.get());
    // 然後我們通過 方法引用 的方式來處理
    Supplier<Long> supplier1 = now::getTime;
    System.out.println(supplier1.get());
}      

方法引用的注意事項:

被引用的方法,參數要和接口中的抽象方法的參數一樣
當接口抽象方法有傳回值時,被引用的方法也必須有傳回值      

2.2.類名::靜态方法名

public class FunctionRefTest04 {

    public static void main(String[] args) {
        Supplier<Long> supplier1 = ()->{
            return System.currentTimeMillis();
        };
        System.out.println(supplier1.get());

        // 通過 方法引用 來實作
        Supplier<Long> supplier2 = System::currentTimeMillis;
        System.out.println(supplier2.get());
    }
}      

2.3 類名::引用執行個體方法

Java面向對象中,類名隻能調用靜态方法,類名引用執行個體方法是用前提的,實際上是拿第一個參數作為方法的調用者

public class FunctionRefTest05 {

    public static void main(String[] args) {
        Function<String,Integer> function = (s)->{
            return s.length();
        };
        System.out.println(function.apply("hello"));

        // 通過方法引用來實作
        Function<String,Integer> function1 = String::length;
        System.out.println(function1.apply("hahahaha"));

        BiFunction<String,Integer,String> function2 = String::substring;
        String msg = function2.apply("HelloWorld", 3);
        System.out.println(msg);
    }
}      

2.4.類名::構造器

由于構造器的名稱和類名完全一緻,是以構造器引用使用​

​::new​

​的格式使用

public class FunctionRefTest06 {

    public static void main(String[] args) {
        Supplier<Person> sup = ()->{return new Person();};
        System.out.println(sup.get());
        // 然後通過 方法引用來實作
        Supplier<Person> sup1 = Person::new;
        System.out.println(sup1.get());
        BiFunction<String,Integer,Person> function = Person::new;
        System.out.println(function.apply("張三",22));
    }
}      

2.5 數組::構造器

數組是怎麼構造出來的呢?

public static void main(String[] args) {
        Function<Integer,String[]> fun1 = (len)->{
            return new String[len];
        };
        String[] a1 = fun1.apply(3);
        System.out.println("數組的長度是:" + a1.length);
        // 方法引用 的方式來調用數組的構造器
        Function<Integer,String[]> fun2 = String[]::new;
        String[] a2 = fun2.apply(5);
        System.out.println("數組的長度是:" + a2.length);
    }