方法引用和構造器引用

1. 方法引用(method reference)

1. 1 何時使用

方法引用Java8 的新特性。

我們知道,使用Lambda表達式可以極大地簡化我們的代碼,但有時候Lambda體中的功能已經有現成的方法實現了,這時我們可以直接使用方法引用,而不是重複地去實現該功能。

方法引用可以理解爲Lambda表達式的另一種表現形式。

1.2 使用前提

方法引用引用的方法的參數列表和返回值類型,必須和函數式接口中抽象方法的參數列表和返回值類型保持一致。

1.3 語法格式

方法引用常用的有3種格式:

1.3.1 實例對象::實例方法名

    public static void main(String[] args) {
        String str = "Hello world";
        Supplier<String> sup = () -> str.toUpperCase();
        System.out.println(sup.get());
    }

上面的代碼中使用了Lambda表達式,表達式中的功能和str對象的toUpperCase()方法一樣,因此,可以直接使用方法引用,如下:

    public static void main(String[] args) {
        String str = "Hello world";
        //Supplier<String> sup = () -> str.toUpperCase();
        Supplier<String> sup = str::toUpperCase;
        System.out.println(sup.get());
    }

另一個例子:

    public static void main(String[] args) {
        String str = "Hello world";
        //傳統的Lambda表達式
        Consumer con = (x) -> System.out.println(x);
        con.accept(str);
        System.out.println("-----------------------");
        // 使用方法引用
        Consumer con1 = System.out::println;
        con1.accept(str);
    }

1.3.2 類名::靜態方法名

    public static void main(String[] args) {
        float a = 3.6f; 
        // 傳統的Lambda表達式
        Function<Float, Integer> fun = (x) -> Math.round(x);
        System.out.println(fun.apply(a));
        System.out.println("-----------------");
        // 使用方法引用
        Function<Float, Integer> fun1 = Math::round;
        System.out.println(fun.apply(a));
    }

1.3.3 類名::實例方法名

public class Person {
    public void say() {
        System.out.println("hello");
    }
    public static void main(String[] args) {
        //傳統Lambda表達式
        Consumer<Person> con = (x) -> x.say();
        con.accept(new Person());
        System.out.println("-------------------");
        // 使用方法引用
        Consumer<Person> con1 = Person::say;
        con1.accept(new Person());
    }
}

腳下留心:若Lambda 的參數列表的第一個參數,是實例方法的調用者,第二個參數(或無參)是實例方法的參數時,格式: ClassName::MethodName,如下所示:

     // 測試兩個字符串是否相等 
    public static void main(String[] args) {
        // 傳統的Lambda表達式
        BiPredicate<String, String> bp = (x, y) -> x.equals(y);
        System.out.println(bp.test("abc", "ab"));
        System.out.println("-----------------");
        // 使用方法引用
        BiPredicate<String, String> bp1 = String::equals;
        System.out.println(bp1.test("abc", "ab"));
    }

2. 構造器引用

2.1 使用前提

使用當構造器的參數列表與函數式接口中抽象方法的參數列表一致。

2.2 語法: 類名::new

    public static void main(String[] args) {
        // 傳統的Lambda表達式
        Function<String, StringBuffer> fun = (x) -> new StringBuffer(x);
        // 使用方法引用
        Function<String, StringBuffer> fun1 = StringBuffer::new;
    }

3. 數組引用

數組引用的使用基本和構造器引用相同。

3.1 語法:類型[]::new

 // 生成指定長度的字符串數組
public static void main(String[] args) {
    // 傳統的Lambda表達式
    Function<Integer, String[]> fun = (e) -> new String[e];
    String[] str = fun.apply(5);
    System.out.println(str.length);
    System.out.println("---------------------------");
    // 使用方法引用
    Function<Integer, String[]> fun1 = String[]::new;
    String[] str1 = fun1.apply(7);
    System.out.println(str1.length);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章