序:一個文件夾下面有不少層的小文件,如何算出這個文件夾下面有多少文件?遞歸遍歷,簡單暴力,遞歸在通常狀況確實是比較方便的解決方案,可是當文件夾深度多深,遞歸的反覆調用會致使方法一直沒法釋放,形成jvm的棧溢出。那咱們該怎麼辦?html
原文和做者一塊兒討論:http://www.cnblogs.com/intsmaze/p/6031894.html
面試
說實話這個問題我之前也沒有遇到過,我是聽一位我很敬佩的IT前輩講的他曾經的面試經歷。他說他當時比較緊張就想到了遞歸,沒有想到其餘的方案。網絡
固然他跟我說這個問題的時候,它也沒有想到好的處理方案。它認爲這種狀況能夠參考網絡爬蟲的遞歸,爲了防止爬蟲在一個深度出不來,一般會設置每一次爬的深度,而後經過各類的限制條件來保證每個文件都被訪問到。數據結構
當時我靈光一閃,由於當時我在溫故數據結構的知識,我說這個文件夾的層次看着好呀嘛好眼熟,不就至關於一個樹的結構,那咱們學數據結構的時候是如何遍歷節點的。有左遞歸,中遞歸,右遞歸,固然這就是上面的遞歸方法,不是咱們要找的解決方案,那麼該怎麼辦?jvm
看,角落裏有咱們常常忽視的層序遍歷。spa
層序遍歷:層序遍歷就是從所在樹的根節點出發,首先訪問第一層的樹根節點,而後從左到右訪問第2層上的節點,接着是第三層的節點,以此類推,自上而下,自左至右逐層訪問樹的結點的過程就是層序遍歷。code
咱們只須要使用一個list集合來存儲每個文件(夾),而後按次序讀取list集合的元素,並判斷若是是文件夾則把該文件夾下的全部文件(夾)追加到list集合後面,而後讀取list的下一個元素以此類推。htm
public class demo { public static void main(String[] args) { List<File> list=new ArrayList<File>(); File file = new File("C:/intsmaze"); list.add(file); for(int i=0;i<list.size();i++) { if(list.get(i).isDirectory()) { File[] tempList = list.get(i).listFiles(); for(int j=0;j<tempList.length;j++) { list.add(tempList[j]); } } } } }
都是有經驗的開發人員,上面的代碼就沒有必要進行註釋了。blog
固然有人會較真,當文件數量不少,就算這代碼能夠保證棧不溢出,可是list集合數量上去了,堆也會爆的。遞歸
固然,這是一種狀況,其實也很簡單,每從集合讀取一個元素,就把該元素從集合溢出,存入硬盤中便可,而後循環裏面的判斷條件中不對i進行遞增便可。
public class demo { public static void main(String[] args) { List<File> list=new ArrayList<File>(); File file = new File("C:/intsmaze"); list.add(file); for(int i=0;i<list.size();) { if(list.get(i).isDirectory()) { File[] tempList = list.get(i).listFiles(); for(int j=0;j<tempList.length;j++) { list.add(tempList[j]); } } list.remove(i); } } }
你們有更好的解決方案能夠一塊兒分享討論.