1. 引言
Java8中最受廣大開發中喜歡的變化之一是因為引入了 lambda 運算式,因為這些運算式允許我們放棄匿名類,從而大大減少了樣板代碼,并提高了可讀性,
方法參考是lambda運算式的一種特殊型別,它們通常通過參考現有方法來創建簡單的lambda運算式,
方法參考包括以下四種型別:
- 靜態方法
- 特定物件的實體方法
- 特定型別的任意物件的實體方法
- 構造方法
在本篇文章中,我們將探討Java中的方法參考,
2. 參考靜態方法
We'll begin with a very simple example, capitalizing and printing a list of Strings:
我們從一個非常簡單的示例開始,字串轉成大寫并列印:
List<String> messages = Arrays.asList("hello", "baeldung", "readers!");
我們可以通過簡單的lambda運算式直接呼叫 StringUtils.capitalize() 方法:
messages.forEach(word -> StringUtils.capitalize(word));
或者,我們可以使用方法參考來簡單地參考 capitalize 靜態方法:
messages.forEach(StringUtils::capitalize);
注意,方法參考應使用::運算子,
3. 參考特定物件的實體方法
為了演示這種型別的方法參考,我們新建以下這兩個類:
public class Bicycle {
private String brand;
private Integer frameSize;
// standard constructor, getters and setters
}
public class BicycleComparator implements Comparator {
@Override
public int compare(Bicycle a, Bicycle b) {
return a.getFrameSize().compareTo(b.getFrameSize());
}
}
創建一個 BicycleComparator 物件來比較自行車尺寸:
BicycleComparator bikeFrameSizeComparator = new BicycleComparator();
我們可以使用lambda運算式按尺寸大小對自行車進行排序,但需要指定兩個自行車實體進行比較:
createBicyclesList().stream()
.sorted((a, b) -> bikeFrameSizeComparator.compare(a, b));
我們可以使用方法參考讓編譯器把句柄引數傳遞給我們:
createBicyclesList().stream()
.sorted(bikeFrameSizeComparator::compare);
4. 參考特定型別任意物件的實體方法
這種型別的方法參考與前面的示例類似,但不必創建自定義物件來執行比較,
讓我們創建一個要排序的Integer 整數串列:
List<Integer> numbers = Arrays.asList(5, 3, 50, 24, 40, 2, 9, 18);
如果我們使用經典的 lambda 運算式,這兩個引數都需要顯式傳遞,而使用方法參考則要簡單得多:
numbers.stream()
.sorted((a, b) -> a.compareTo(b));
numbers.stream()
.sorted(Integer::compareTo);
盡管它仍然是一行代碼,但是方法參考更容易閱讀和理解,
5. 參考建構式
我們可以像在第一個例子中參考靜態方法一樣參考建構式,唯一區別是需要使用new關鍵字,
現在我們用不同品牌的String串列創建一個Bicycle陣列:
List<String> bikeBrands = Arrays.asList("Giant", "Scott", "Trek", "GT");
首先,我們將向Bicycle類添加一個新的建構式:
public Bicycle(String brand) {
this.brand = brand;
this.frameSize = 0;
}
接下來,我們將使用方法參考中的新建構式,并從原始的String串列中生成一個Bicycle陣列:
bikeBrands.stream()
.map(Bicycle::new)
.toArray(Bicycle[]::new);
注意如何使用方法參考呼叫Bicycle和Array建構式,從而使代碼看起來更加簡潔明了,
6. 其他示例和限制
目前為止,方法參考是一個使代碼非常清晰和易讀的好方法,但是,我們不能用它們來代替各種lambda運算式,因為它們有一些局限性,
它們的主要局限性是由于它們最大的優點:前一個運算式的輸出需要與參考的方法宣告的輸入引數匹配,
看看這個限制的例子:
createBicyclesList().forEach(b -> System.out.printf(
"Bike brand is '%s' and frame size is '%d'%n",
b.getBrand(),
b.getFrameSize()));
這個簡單的例子不能用方法參考來表示,因為在我們的例子中,printf 方法需要3個引數,而使用createBicyclesList().forEach()只允許方法參考一個引數(Bicycle物件),
最后,我們研究下,如何創建一個可以從lambda運算式參考的no-operation函式,
在本例中,我們希望使用lambda運算式而不使用其引數,
首先,創建 doNothingAtAll 方法:
private static <T> void doNothingAtAll(Object... o) {
}
因為這是一個varargs方法,它可執行在任意 lambda 運算式中,而不管參考的物件或引數的數量,我們看看它的作用:
createBicyclesList()
.forEach((o) -> MethodReferenceExamples.doNothingAtAll(o));
7. 總結
在這篇文章中,我們學習了Java中的方法參考,以及如何使用它們來替換lambda運算式,從而提高了可讀性并闡明編程的意圖,
如果你覺得文章還不錯,記得關注公眾號: 鍋外的大佬
鍋外的大佬博客
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/231448.html
標籤:Java
上一篇:WEB網站登錄系統
