今天是我自學Java的第38天。
感謝你的觀看,謝謝你。
話不多說,開始今天的學習:
遞歸:不要看這個名字好像挺高大上的樣子,其實理解起來還是蠻容易的。
在學習遞歸之前,我們先學習下目錄的遍歷,遞歸的主要使用途徑就需要它。
一、目錄的遍歷
目錄,自然也就是指我們常說的文件夾了,一個文件夾裡面是可以有很多個子文件夾和子文件的。
如果遍歷目錄?有兩種方法:
1.目錄的遍歷:list方法
①創建一個文件對象
因為是目錄的遍歷,所以在路徑中填寫目錄的路徑。②list方法
list,列表的意思,一個文件夾裡面有幾個文件夾或者文件,這就是一個獲取文件夾裡的列表的方法。
返回一個String數組,表示該File目錄中的所有子文件或目錄。
③遍歷目錄
使用增強for循環,控制臺會輸出一個目錄列表。
2.目錄的遍歷:listFiles方法
①創建一個文件對象
②listFiles方法
返回一個File數組,表示該File目錄中的所有的子文件或目錄。
③遍歷目錄
使用增強for循環,控制臺會輸出一個目錄列表(帶完整路徑的)。
其中可以使用file的getName方法獲取文件名列表。
目錄的遍歷特點:
只能遍歷目錄,不能遍歷文件。listFiles方法更加地常用,因為file有各種各樣的方法,我們可以根據需求遍歷出不同的格式。因為File根據構造方法的路徑,既能表示成文件又能表示成目錄,如果填寫文件路徑會返回null,遍歷的話就會出現空指針異常。二、遞歸(recursion)
說到遞歸,先提一個數學裡的概念:階乘。
什麼叫階乘?
5的階乘:5!=5×4×3×2×1;
4的階乘:4!=4×3×2×1。
這就是階乘。
現有一個需求:求一個數的階乘?
1.for循環解決該需求
看到這個需求我的第一個反應就是for循環,事實上確實可以用循環語句解決:
①定義一個計算階乘的方法:getResult()。
②在getResult中,定義一個變量作為階乘的結果。
③for循環計算階乘,並返回結果。
注意:0!=1,而不是想當然的以為等於0;
至於為什麼為1,這是一個數學問題。
本質上n!=(n+1)!÷(n+1);
所以:0!=1!÷1=1。
那除了for循環還有沒有其他方法呢?
答案是有的,也就是遞歸。
2.遞歸解決該需求
①定義一個計算階乘的方法。
②i==0,0的階乘等於1,直接返回1。
③i>0時,找出其中的計算規律。
如果getResult(i-1)就是(i-1)!
那麼getResult(i)=i*getResult(i-1)。
看到沒有,什麼叫遞歸?
遞歸就是指在方法裡面調用自己的方法這種現象。
就像我們在數學中的找規律一樣,先把規律找出來,再創建方法。
④如果是負數,因為負數是沒有階乘的,直接返回-1,或者報錯。
遞歸注意點:
遞歸必須要有結束條件,不然的話就是死循環了。stackOverflowError : 棧溢出,如下圖:
因為遞歸指的是方法裡面調用自己的方法,如果一次性地調用次數過多會出現棧溢出的情況,並且這是一種錯誤,無法從代碼角度修改。
其中上述兩種方法中:
for循環的方法要更加地實用簡潔,使用遞歸的話效率會很低,一般使用的很少。
那為何還要學遞歸?
因為它在文件操作中會使用到它,並且既然是學習Java,也有必要理解下遞歸的概念。
三、遞歸刪除多級目錄
根據我們昨天學的File類中的方法。
刪除方法delete只能用來刪除文件和空文件夾,它是沒法直接刪除非空文件夾的。
那你可能要問了,那計算機裡面可以直接刪除一個非空文件夾的呀,它是怎麼做到的?
其實刪除非空文件夾的操作本質上就是:先將文件夾裡面的所有文件都刪除,等自己成一個空文件夾了,再刪除自己。
這個需求如何實現?
就需要使用到遞歸。
①創建file對象,定義一個deleteFile的方法
其中路徑為多級文件夾,所以不能用delete方法直接刪除,deleteFile方法可以用來刪除一個文件夾。
②delete方法中如果file對象是文件
是文件的話,可以使用delete方法直接刪除。
③如果是文件夾,我們需要遍歷
將文件夾遍歷,使用我們一開始學到的listFiles方法。
遍歷之後,文件夾裡面也是有可能既包含文件夾又包含文件的,還是要判斷,又回到了一開始的需求。
④遞歸
在方法裡直接調用自己的方法就好了。
⑤刪除空文件夾
因為文件夾裡的文件夾和文件都沒有了,就是一個空文件夾了,所以可以直接刪除。
總之,使用遞歸把握兩點:
如何結束遞歸?如何繼續遞歸?上述例子中:
如何結束遞歸?
當file對象是一個文件時(使用isFile方法),直接就可以刪除文件了,結束遞歸。
如何繼續遞歸?
我們是要刪除一個文件夾,使用了一個deleteFile方法。
因為一個文件夾裡面是可能既有文件夾又有文件的。
如果是文件,直接刪除。如果是文件夾,繼續使用deleteFile方法說白了,遞歸就是尋找邏輯點相同的地方,再自己調用自己的方法就好了。
總結