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);
}