摘要:方法引用在之前只能進行值傳遞,方法是不能傳遞的。首先方法接受了一個類型的對象,方法是獲取所有的文件,是用來存儲篩選之后的元素,循環所有獲得到的文件數組,然后調用中的方法來進行條件篩選,放入后返回。
方法引用:
在Java 8之前只能進行值傳遞,方法是不能傳遞的。如果你想調用一個方法你必須先獲取到它所在的類的實例,然后再通過實例去調用這個方法,但是Java 8新增了方法引用這個新特性可以讓你直接把方法當做值來傳遞。
1.下面這段代碼代碼的作用是遍歷獲取目錄下所有的文件和目錄,并且還加了一個篩選條件,只篩選出不隱藏的文件和目錄,這里我們其實只是想調用FileFilte中的accept方法來進行篩選,但是我們需要先創建FileFilter的匿名對象,然后重寫整個accept方法,這樣我們才調用到了這個方法,其中只有第三行代碼是會有變化的,其他的代碼都是固定的,但是我們每次還是要把其他固定的模板代碼重新寫一遍。
File[] hiddenFiles = new File("F: est").listFiles(new FileFilter() { public boolean accept(File file) { return !file.isHidden(); } });
2.現在Java 8中的方法引用就解決了這個問題,讓我們看下列的代碼,我們發現匿名類和重寫方法的步驟都已經沒有了,上述代碼的本質其實就是調用傳進來的File對象的isHidden方法,現在File:: isHiden這個寫法就是和上面的代碼是同樣的作用,但是代碼精簡了很多,那些無用的冗余代碼都不見了。
File[] hiddenFiles = new File("F: est").listFiles(File::isHidden);
3.我們從源碼來看看listFiles方法做了什么操作,而這兩種寫法又有什么不同。
首先listFiles方法接受了一個FileFilter類型的對象,list方法是獲取所有的文件,files是用來存儲篩選之后的元素,循環所有獲得到的文件數組,然后調用FileFilter中的accept方法來進行條件篩選,放入files后返回。
public File[] listFiles(FileFilter filter) { String ss[] = list(); if (ss == null) return null; ArrayListfiles = new ArrayList<>(); for (String s : ss) { File f = new File(s, this); if ((filter == null) || filter.accept(f)) files.add(f); } return files.toArray(new File[files.size()]); }
再看看FileFilter對象是什么,發現它是一個接口,所以Java 8之前的寫法都是寫了個匿名對象來實現這個接口,重寫它的accept方法。看到這里其實很明顯了,這就是一個策略模式的應用。而方法引用就是讓我們直接把需要在accept方法里調用的方法傳遞進去,不需要像以前一樣來個全家桶寫一堆固定模板。
@FunctionalInterface public interface FileFilter { boolean accept(File pathname); }
4.下面的圖介紹了Java 8之前和之后這段代碼的邏輯流程,在Java 8之前是需要先創建FileFilter匿名對象然后再調用File.listFiles方法,而現在只需要File::isHiden寫法就可以達到同樣的目的,其實它的含義就是創建了一個方法引用,所以你可以通過傳遞引用來傳遞這個方法,就好像你new了一個對象的引用,然后你把這個引用傳遞到別的地方,你就可以調用這個對象里的屬性和方法是一樣的道理。
Lambda-匿名函數:上面的方法引用讓我們可以把方法也當做值來進行傳遞,但是有時候我們傳遞進去的代碼并沒有像File.isHidden方法一樣封裝起來,而這種情況也是經常發生的,有時候為了一個特殊需求我需要寫段代碼來解決,但是次數用的極少,沒必要封裝個方法,而Lambda表達式則解決了這個問題。
1.比如我們想要篩選出一個文件名叫abc.txt的文件,我們可以這樣寫,我們看到 file.getName(). equals("abc.txt"));是我們自己寫出來的,我們并沒有把它封裝成方法就拿來使用了,注意看->符號前面,那個代表的是上面accept方法接受的參數,而->后面則是我們拿傳遞進來的參數來操作,只是要確保你的這行代碼返回的類型是要和accept方法的返回類型一致。
File[] files3 = new File("F: est").listFiles((File file) -> file.getName().equals("abc.txt"));
2.以上只是Lambda表達式最簡單的方式,我們還可以有下列這些更加多樣化的操作,Lambda表達式在Java 8中是非常重要的部分,因為后面我們講到的stream(流)就是基于它來使用的。
//單個參數的時候可以省略括號和類型,直接寫形參 File[] files4= new File("F: est").listFiles((file -> file.getName().equals("abc.txt"))); //如果要寫多行代碼,可以加大括號把所有代碼括起來,最后你同樣需要返回正確的類型 File[] files5= new File("F: est").listFiles( (File file) -> { boolean flag = file.getName().equals("d") && file.getName().contains("d"); return flag; } );
下面我會增加一篇文章關于Lambda表達式的實際應用,好讓大家更好的理解它們的用法。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71433.html
摘要:歐陽思海繼承接口后,又加了新的抽象方法,這個接口就不再是函數式接口默認方法在接口中添加了一個默認方法。總結在這篇文章中,我們講了表達式方法引用函數式接口接口中的靜態方法接口中的默認方法的使用。 今天我來聊聊 Java8 的一些新的特性,確實 Java8 的新特性的出現,給開發者帶來了非常大的便利,可能剛剛開始的時候會有點不習慣的這種寫法,但是,當你真正的熟悉了之后,你一定會愛上這些新的...
摘要:概述簡介若體中的功能,已經有方法提供了實現,可以使用方法引用可以將方法引用理解為表達式的另外一種表現形式方法引用的三種形式對象的引用實例方法名類名靜態方法名類名實例方法名注意方法引用所引用的方法的參數列表與返回值類型,需要與函數式接口中抽象 1. 概述 1.1 簡介 若 Lambda 體中的功能,已經有方法提供了實現,可以使用方法引用(可以將方法引用理解為 Lambda 表達式的另外一...
摘要:實際上方法引用是表達式的一種語法糖。小結本篇全面介紹了方法引用的四種使用方式,且每種方式都有對應一個示例來幫助大家理解。 上一篇我們詳細介紹了Optional類用來避免空指針問題,本篇我們全面了解一下Java8中的方法引用特性。方法引用是lambda表達式的一種特殊形式,如果正好有某個方法滿足一個lambda表達式的形式,那就可以將這個lambda表達式用方法引用的方式表示,但是如果這...
摘要:大家好,我是樂字節的小樂,上一次我們說到了核心特性之函數式接口,接下來我們繼續了解又一核心特性方法引用。方法引用是一種更簡潔易懂的表達式。感謝光臨閱讀小樂的,敬請關注樂字節后續將繼續講述等前沿知識技術。 大家好,我是樂字節的小樂,上一次我們說到了Java8核心特性之函數式接口,接下來我們繼續了解Java8又一核心特性——方法引用。 showImg(https://segmentfaul...
摘要:表達式簡介表達式是一個匿名函數對于而言并不很準確,但這里我們不糾結這個問題。如果表達式的正文有一條以上的語句必須包含在大括號代碼塊中,且表達式的返回值類型要與匿名函數的返回類型相同。 版權聲明:本文由吳仙杰創作整理,轉載請注明出處:https://segmentfault.com/a/1190000009186509 1. 引言 在 Java 8 以前,若我們想要把某些功能傳遞給某些方...
閱讀 3858·2023-04-26 00:36
閱讀 2667·2021-11-16 11:44
閱讀 1082·2021-11-15 17:58
閱讀 1665·2021-09-30 09:47
閱讀 1208·2019-08-30 13:05
閱讀 1539·2019-08-30 12:55
閱讀 2409·2019-08-30 11:02
閱讀 2717·2019-08-29 17:01