Java 8的方法引用詳解(讓你的代碼看起來高大上)
在上一篇文章中曾經(jīng)介紹到了java8中的Lambda表達式,這篇文章是基于Lambda表達式來敘述的。主要講解方法引用。在此之前還希望你能夠了解一下函數(shù)式接口的使用。
一、什么是方法引用
在Lambda表達式中,將其劃分了幾塊。這一行就是lambda表達式。() -> System.out.println("使用Lambda表達式");下面我們對lambda的格式進行一個介紹:
(1)左邊括號:lambda的形參列表,就好比是我們定義一個接口,里面有一個抽象方法,這個抽象方法的形參列表。
(2)箭頭:lambda的操作符,所以你看見這個箭頭心中知道這是一個lambda表達式就可以了。
(3)右邊lambda體:就好比是我們實現(xiàn)了接口中的抽象方法。
在最后一塊中,有時候,lambda體可能僅僅調(diào)用一個已存在的方法,而不做任何其它事,對于這種情況,通過一個方法名字來引用這個已存在的方法會更加清晰。
所以我們來總結(jié):方法引用是一個更加緊湊,易讀的 Lambda 表達式,注意方法引用是一個 Lambda 表達式,其中方法引用的操作符是雙冒號 "::"。
二、舉例演示
1、我們首先定義一個User類

現(xiàn)在有一個功能,那就是需要按照年齡,對Person進行排序。
2、Lambda表達式寫法

我們使用lambda表達式可以直接進行比較。現(xiàn)在我們使用方法引用。

這下子代碼是不是更加的簡潔了。我們相當(dāng)于把lambda表達式進行了改變。下面我們就來好好地講解一下方法引用是如何使用的。
三、方法引用分類
先來說一下方法引用使用到的操作符“::”,這個操作符把方法引用分成兩邊,左邊是類名或者某個對象的引用,右邊是方法名。引用方法有下面幾種方式:
(1)對象引用::實例方法名
(2)類名::靜態(tài)方法名
(3)類名::實例方法名
(4)類名::new
(5)類型[]::new
我們對這5種方式分別來敘述。
1、對象引用::實例方法名

我們創(chuàng)建了一個PersonCompare對象,調(diào)用了其內(nèi)部的compareByName實例方法。
2、類名::靜態(tài)方法名
舉幾個例子:
String::valueOf,等價于 Lambda:s -> String.valueOf(s)
Math::pow 等價于lambda表達式 (x, y) -> Math.pow(x, y);
Person::compareByAge 就是一個靜態(tài)方法引用,也是前面我們舉得例子。
Function<Long, Long> f = Math::abs; Long result = f.apply(-3L);123
Math是一個類而abs為該類的靜態(tài)方法。Function中的唯一抽象方法apply方法參數(shù)列表與abs方法的參數(shù)列表相同,都是接收一個Long類型參數(shù)。
3、類名::實例方法名
若Lambda表達式的參數(shù)列表的第一個參數(shù),是實例方法的調(diào)用者,第二個參數(shù)(或無參)是實例方法的參數(shù)時,就可以使用這種方法:
BiPredicate<String, String> b = String::equals; b.test("abc", "abcd");
String是一個類而equals為該類的定義的實例方法。BiPredicate中的唯一抽象方法test方法參數(shù)列表與equals方法的參數(shù)列表相同,都是接收兩個String類型參數(shù)。
4、類名::new
在引用構(gòu)造器的時候,構(gòu)造器參數(shù)列表要與接口中抽象方法的參數(shù)列表一致。對應(yīng)的 Lambda:() -> new String()。

上面這段代碼的功能就是使用PersonFactory工廠,然后使用Person::new創(chuàng)建一個Person實例。
5、類型[]::new
引用數(shù)組和引用構(gòu)造器很像,格式為 類型[]::new,等價于 lambda 表達式 x -> new int[x]。其中類型可以為基本類型也可以是類。

OK。方法引用就是這么簡單。