?今天是我自學(xué)Java的第40天唬党。
感謝你的觀看鹃共,謝謝你。
話不多說驶拱,開始今天的學(xué)習(xí):
昨天學(xué)習(xí)了過濾器霜浴,它的作用在于能夠過濾出滿足一定條件的文件。跟著依樣畫葫蘆蓝纲,我自己也寫了一個過濾器阴孟。
正當(dāng)我滿以為自己對面向接口編程這一思想掌握的還算不錯時,結(jié)果被瘋狂的嘲諷税迷。
并且覺得他們說的也還蠻有道理的永丝,自己確實很菜,不能坐井觀天箭养,要有敬畏之心慕嚷。
所以我想了想,決定擼下文件過濾器的源碼毕泌,我確實寫的菜喝检,但Java里的源碼是Java開發(fā)者幾十年來智慧的結(jié)晶,總不能說它菜了吧撼泛?
對于我這樣的Java萌新來說挠说,看源碼確實是一件比較吃力的事情,這也是自己一直比較恐懼的事情坎弯。
但人在嘲笑中變強(qiáng)纺涤,所以我想試一試译暂。
一、JDK中的文件過濾器
昨天是我自己定義了一個過濾器接口撩炊。
其實在JDK中外永,Java底層已經(jīng)定義好了一個過濾器接口,源碼如下:
①接口FileFilter
File文件拧咳,F(xiàn)ilter過濾器伯顶,顧名思義,這就是專門用來解決文件過濾問題的接口骆膝。
②方法accept
參數(shù):File對象祭衩;返回值:布爾值。
如果返回值為真阅签,就將file保存下來掐暮;
如果返回值為假,就將file不保存政钟。
具體的過濾條件路克,在重寫accept方法時說明就好了。
該接口只有一個方法养交,也就是說其為函數(shù)式接口精算,所以可以使用lambda表達(dá)式。
二碎连、JDK中過濾器的封裝
JDK將過濾器封裝在listFiles方法中了灰羽。
listFiles方法有幾個重載方法:
listFiles():遍歷文件夾中的子文件或者子文件夾。
listFiles(FileFilter filter):按照過濾條件遍歷文件夾中對應(yīng)的子文件或者子文件夾鱼辙。
JDK中源碼如下:
我們來一步一步地分析:
①listFiles(FileFilter filter)
參數(shù):FileFilter接口廉嚼,那么我們?nèi)羰且{(diào)用這個方法,必須要傳入FileFilter接口的實現(xiàn)類對象(使用匿名內(nèi)部類或者lambda表達(dá)式)座每。
返回值:一個文件數(shù)組前鹅。
②String ss[]=list()
這個是啥呢摘悴?這里省略了一個this關(guān)鍵字峭梳。
也就是this.list(),F(xiàn)ile類有一個list方法蹂喻,也是用來文件夾的遍歷葱椭,給一個文件對象,返回一個字符串?dāng)?shù)組口四。
file對象在調(diào)用listFiles方法時孵运,其底層也會調(diào)用一次list方法,如果字符串?dāng)?shù)組為空蔓彩,那么直接返回空治笨。
③ArrayList<File> files = new ArrayList<>();
創(chuàng)建一個ArrayList集合files驳概,泛型為File,也就是說files這個集合只能用來存儲File對象旷赖。
④for(String s::ss){}顺又;
增強(qiáng)for循環(huán)遍歷ss,遍歷出來的也就是子文件或者子文件夾對應(yīng)字符串名字等孵。
⑤File f = new File(s, this);
這是新創(chuàng)建了一個file對象稚照,相當(dāng)于遍歷出來的子文件或者子文件夾。
⑥if ((filter == null) || filter.accept(f))
如果過濾器filter為空或者filter接口中accept方法的返回值為真俯萌,也就是我們實現(xiàn)接口后果录,重寫accept方法的返回值。
只要它們有一樣為真咐熙,就將⑤中的文件對象添加到③中的集合當(dāng)中弱恒,也就是代碼中的files.add(f)
⑦return files.toArray(new File[files.size()]);
返回一個file數(shù)組,將③中的files集合轉(zhuǎn)換成一個file數(shù)組棋恼,數(shù)組長度斤彼,也就是files集合的大小。
以上就是jdk已經(jīng)封裝好了的文件過濾器蘸泻,我們在直接使用listFiles方法中的琉苇。
三、使用jdk提供的文件過濾器
1.過濾單級文件夾
直接調(diào)用listFiles(FileFilter filter)方法就可以了:
①創(chuàng)建文件對象
路徑也就是右邊作為測試的文件夾悦施。
②調(diào)用listFiles(FileFilter filter)方法
因為參數(shù)是FileFilter接口并扇,我們使用匿名內(nèi)部類代替其子類對象,重寫accept方法抡诞,并寫出過濾條件穷蛹。
③重寫accept方法
方法為endsWith("jpg"),也就是過濾出后綴名為“jpg”的圖片昼汗。
④遍歷過濾后的files數(shù)組并打印净刮。
運行結(jié)果嘲驾,會發(fā)現(xiàn)控制臺輸出了該文件夾下的所有圖片文件。
很簡單,直接調(diào)用jdk已經(jīng)封裝好了的方法就好了座哩。
但是這樣還是有一個問題知态,它只能過濾出該文件夾下的圖片文件识腿,不能過濾多級文件夾折欠,那該怎么辦?
2.過濾多級文件夾
要解決這個問題谓着,得使用到遞歸泼诱,當(dāng)然昨天有小伙伴評論說迭代,這我不懂赊锚,暫時只學(xué)了遞歸治筒,也只會它屉栓。
①創(chuàng)建file對象,并定義find方法
要使用遞歸耸袜,首先定義一個方法系瓢,不然也沒法自己調(diào)用自己。
②如果是文件(isFile方法)
遞歸結(jié)束句灌,并打印過濾后的文件夷陋。
③調(diào)用listFiles(FileFilter filter)方法
參數(shù)是接口,傳參數(shù)時需要使用其實現(xiàn)類胰锌。
④設(shè)定過濾條件
在第二節(jié)中使用了匿名內(nèi)部類骗绕,這里使用lambda表達(dá)式,也就是函數(shù)式編程资昧。
后綴名為“jpg“的文件保留下來酬土。
同時如果是子文件夾也要保持下來,這點很關(guān)鍵格带,一個文件夾里面是可能會有子文件夾的撤缴,并且子文件夾里也有可能有圖片文件。
⑤將過濾后的文件遍歷叽唱,并遞歸
代碼寫完后屈呕,執(zhí)行就可以過濾出多級文件夾里的圖片文件了。