Java雙冒號(hào)(::)運(yùn)算符使用詳解
1.說(shuō)明
之前沒(méi)用過(guò)::這個(gè)東西,今天看flink的時(shí)候發(fā)現(xiàn)官網(wǎng)有個(gè)例子用到了這個(gè)符號(hào), 本著求知欲去百度查了一番,沒(méi)找到能說(shuō)到我心里去的解釋,本著求知欲的態(tài)度,我去了官網(wǎng)看了看. java ::
2.先來(lái)說(shuō)下@FunctionalInterface
java8 lambda 內(nèi)部接口需要@FunctionalInterface這個(gè)注解,這個(gè)注解是一個(gè)說(shuō)明性質(zhì)的注解,被@FunctionalInterface注解的接口只能由一個(gè)抽象方法,@FunctionalInterface只能用于注解接口而不能用在class以及枚舉上.
被@FunctionalInterface注解的符合規(guī)則的接口,可以用lambda表達(dá)式. 下面舉一個(gè)例子:
public class Main { public static void pr(String s){ System.out.println(s); } public static void main(String[] args) throws Exception { List<String> list = Arrays.asList("aaaa", "bbbb", "cccc"); list.forEach(s -> System.out.println(s)); } }
所以說(shuō),@FunctionalInterface用于lambda樣式說(shuō)明.
3. 下面來(lái)講講這個(gè) "::"是干嘛的
"::"官網(wǎng)對(duì)這個(gè)符號(hào)的解釋是方法引用,也就是引用一個(gè)方法的意思,英文名稱Method References
lambda expressions 可以用來(lái)創(chuàng)建一匿名的方法, 這個(gè)匿名的方式你需要自己實(shí)現(xiàn).
1. list.forEach(new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }); 2. list.forEach(s -> System.out.println(s));
上面兩種寫(xiě)法是一樣的,下面就是lambda表達(dá)式.
上面說(shuō)了lambda表達(dá)式你需要自己實(shí)現(xiàn),但是有些時(shí)候這不是必要的,比如你的項(xiàng)目里某個(gè)地方存在了一個(gè)符合當(dāng)前邏輯的lambda表達(dá)式的方法, 那么我是否可以直接拿來(lái)用?, 答案是可以, 程序追求的就是不重復(fù)極簡(jiǎn)的思想, 既有則拿來(lái)用即可,為什么還要自己實(shí)現(xiàn)呢. Method References 就是用來(lái)做這件事的.
在看下面的例子之前讀者需要知道java 比較器,否則看不懂代碼.
4. 建立一個(gè)Person類
public class Person implements Comparable<Person>{ public String name; public int age; @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Person(String name, int age) { this.name = name; this.age = age; } public static int compareByAge(Person a, Person b) { return a.compareTo(b); } @Override public int compareTo(Person o) { if (this.age > o.age){ return -1; }else{ return 1; } } }
4:構(gòu)建多個(gè)person對(duì)象,放入數(shù)組中,然后對(duì)數(shù)組中的person重新排序
public class Test { //編寫(xiě)Comparator,Person的age private static final Comparator<Person> COMPARATOR = new Comparator<Person>() { public int compare(Person a, Person b) { return a.compareTo(b);//運(yùn)用User類的compareTo方法比較兩個(gè)對(duì)象 } }; public static void main(String[] args) { Person one = new Person("張三",50); Person two = new Person("李四",100); ArrayList<Person> array = new ArrayList<>(); array.add(one); array.add(two); Collections.sort(array,COMPARATOR); System.out.println(array); } } //輸出結(jié)果: //[Person{name='李四', age=100} //Person{name='張三', age=50}]
仔細(xì)看上面的代碼,重點(diǎn)在Collections.sort(array,COMPARATOR);這一行,sort接收兩個(gè)參數(shù),第一個(gè)是要被排序的數(shù)組,第二個(gè)是一個(gè)比較器對(duì)象Comparator,其源碼如下,我只粘貼了必要的部分.
**@FunctionalInterface** public interface Comparator<T> { int compare(T o1, T o2); }
@FunctionalInterface我們知道,被這個(gè)注解修飾的接口可以用lambda表達(dá)式的.
所以我們將class Test改成下面的樣子:
public class Test { public static void main(String[] args) { Person one = new Person("張三",50); Person two = new Person("李四",100); ArrayList<Person> array = new ArrayList<>(); array.add(one); array.add(two); Collections.sort(array, (a, b) -> a.compareTo(b)); System.out.println(array); } }
注意:下面是lambda寫(xiě)法,和正常傳統(tǒng)寫(xiě)法
Collections.sort(array, (a, b) -> a.compareTo(b)); 和下面的等效 Collections.sort(array, new Comparator() { @Override public int compare(Person a, Person b) { return a.compareTo(b); } });
5:揭秘 "::"符號(hào)
到這里其實(shí)我們上面的功能已經(jīng)完成了,我們來(lái)分析一下代碼.
1:構(gòu)造了兩個(gè)對(duì)象
2:把對(duì)象放入了數(shù)組
3:Collection.sort(array,Comparator<T>) 對(duì)數(shù)組進(jìn)行排序
關(guān)鍵點(diǎn)在于:Comparator<T> 比較器,它是一個(gè)被@FunctionalInterface修飾的接口,我們一般成為函數(shù)式接口.
因此,Collection.sort(array,Comparator<T>) ,對(duì)于第二個(gè)參數(shù)Comparator<T>,我們可以傳入一個(gè)匿名實(shí)現(xiàn)類,然后實(shí)現(xiàn)里面的 int compare(T o1, T o2) 方法,也可以寫(xiě)成lambda表達(dá)式的樣子,到這里如果你都懂了,那么接下來(lái)就好說(shuō)了,如果沒(méi)明白,回頭接著看,相信自己騷年. 下面我們重點(diǎn)看lambda方式的寫(xiě)法,這和"::"息息相關(guān)
Collections.sort(array, (a, b) -> a.compareTo(b));
- **(a, b) -> a.compareTo(b)**這個(gè)其實(shí)就是匿名函數(shù), 該函數(shù)的參數(shù)分別是Person a, Person b
- a.compareTo(b) 是該匿名函數(shù)的邏輯,
也即是說(shuō)我們寫(xiě)出來(lái)的這個(gè)匿名函數(shù)有兩個(gè)參數(shù),以及一個(gè)調(diào)用compareTo的函數(shù)體,到這里其實(shí)結(jié)束了,一開(kāi)始我們就說(shuō)了,符號(hào)"::"的意義就是用一個(gè)已經(jīng)存在的函數(shù)代替我們lambda表達(dá)式中的函數(shù)體,只要這個(gè)存在的函數(shù)和lambda函數(shù)體的函數(shù)格式一致就行了. 格式其實(shí)就是參數(shù)個(gè)數(shù),和參數(shù)類型下面是新的class Test揭示了答案
public class Test { public static void main(String[] args) { Person one = new Person("張三",50); Person two = new Person("李四",100); ArrayList<Person> array = new ArrayList<>(); array.add(one); array.add(two); Collections.sort(array, Person::compareByAge);//寫(xiě)法一 // Collections.sort(array, one::entyMethod);//寫(xiě)法二 System.out.println(array); } }
附官網(wǎng)的一句話:
Because this lambda expression
invokes an existing method,
you can use a method reference
**instead of** a lambda expression
Collections.sort(array, Person::compareByAge); Collections.sort(array, one::entyMethod);
這兩種寫(xiě)法都是可行的.
6.0 方法引用的支持如下
我們上面講了靜態(tài)方法,和類方法的代替方式,至于其他的這里不講了,主要是我要去吃飯了.
到此這篇關(guān)于Java雙冒號(hào)(::)運(yùn)算符使用詳解的文章就介紹到這了,更多相關(guān)Java雙冒號(hào)(::)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java數(shù)組實(shí)現(xiàn)隊(duì)列及環(huán)形隊(duì)列實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了java數(shù)組實(shí)現(xiàn)隊(duì)列及環(huán)形隊(duì)列實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10Spring的@RequestParam對(duì)象綁定方式
這篇文章主要介紹了Spring的@RequestParam對(duì)象綁定方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10SpringBoot整合ShardingSphere5.x實(shí)現(xiàn)數(shù)據(jù)加解密功能(最新推薦)
這篇文章主要介紹了SpringBoot整合ShardingSphere5.x實(shí)現(xiàn)數(shù)據(jù)加解密功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06SpringBoot靜態(tài)資源映射規(guī)則淺析
這篇文章主要介紹了SpringBoot靜態(tài)資源映射規(guī)則,今天在玩SpringBoot的demo的時(shí)候,放了張圖片在resources目錄下,啟動(dòng)區(qū)訪問(wèn)的時(shí)候,突然好奇是識(shí)別哪些文件夾來(lái)展示靜態(tài)資源的, 為什么有時(shí)候放的文件夾不能顯示,有的卻可以2023-02-02Java定時(shí)清理過(guò)期文件的實(shí)例代碼
這篇文章主要介紹了Java定時(shí)清理過(guò)期文件的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-12-12簡(jiǎn)單談?wù)凷pringMVC轉(zhuǎn)發(fā)和重定向的區(qū)別
下面小編就為大家?guī)?lái)一篇簡(jiǎn)單談?wù)凷pringMVC轉(zhuǎn)發(fā)和重定向的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06