------- android培訓、java培訓、期待與您交流! ----------
20.01 遞歸概述和注意事項
遞歸:方法定義中調用方法本身的現象
遞歸注意事項:
1.要有出口,否則就是死遞歸
2.次數不能太多,否則就內存溢出
3.構造方法不能遞歸使用
20.02 遞歸求階乘的代碼實現及內存圖解例:
1 public class PRactice 2 { 3 public static void main(String[] args) 4 { 5 System.out.println(jieCheng(5)); 6 } 7 public static int jieCheng(int i) 8 { 9 if(i == 1)10 return 1;11 else12 return i * jieCheng(i - 1);13 }14 }

20.03 不死神兔問題案例
有一對兔子,從出生后第3個月起每個月都生一對兔子,小兔子長到第三個月后每個月又生一對兔子,假如兔子都不死,問第二十個月的兔子對數為多少?
第1個月:1 第2個月:1 第3個月:2
第4個月:3 第5個月:5 第6個月:8
...
由此可見兔子對象的數據是:1,1,2,3,5,8...
規則:A:從第三項開始,每一項是前兩項之和
B:而且說明前兩項是已知的
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 //方式1:數組實現 6 int[] arr = new int[20]; 7 arr[0] = 1; 8 arr[1] = 1; 9 for(int i = 2 ; i < arr.length; i++)10 {11 arr[i] = arr[i - 2] + arr[i - 1];12 }13 System.out.println(arr[19]);14 System.out.println("------");15 //方式2:變量的變化實現16 int a = 1;17 int b = 1;18 for (int i = 0; i < 18; i++) 19 {20 int temp = a;21 a = b;22 b = temp + b;23 }24 System.out.println(b);25 System.out.println("------");26 //方式327 System.out.println(sum(20));28 }29 //方式3:遞歸實現30 public static int sum(int i)31 {32 if(i == 1 || i == 2)33 return 1;34 else35 return sum(i - 1) + sum(i - 2);36 }37 }20.04 遞歸輸出指定目錄下所有的java文件的絕對路徑案例
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 File f = new File("E://javaSE"); 6 getAllJavaFilePaths(f); 7 } 8 public static void getAllJavaFilePaths(File srcFolder) 9 {10 // 獲取該目錄下所有的文件或者文件夾的File數組11 File[] fileArray = srcFolder.listFiles();12 13 // 遍歷該File數組,得到每一個File對象14 for (File file : fileArray) 15 {16 // 判斷該File對象是否是文件夾17 if (file.isDirectory()) 18 {19 //如果是目錄繼續進入20 getAllJavaFilePaths(file);21 } 22 else 23 {24 // 繼續判斷是否以.java結尾25 if (file.getName().endsWith(".java")) 26 {27 // 就輸出該文件的絕對路徑28 System.out.println(file.getAbsolutePath());29 }30 }31 }32 }33 }20.05 遞歸刪除帶內容的目錄案例
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 File f = new File("D://demo"); 6 deleteFolder(f); 7 } 8 private static void deleteFolder(File srcFolder) 9 {10 // 獲取該目錄下的所有文件或者文件夾的File數組11 File[] fileArray = srcFolder.listFiles();12 if (fileArray != null) 13 {14 // 遍歷該File數組,得到每一個File對象15 for (File file : fileArray) 16 {17 // 判斷該File對象是否是文件夾18 if (file.isDirectory()) 19 {20 deleteFolder(file);21 }22 else 23 {24 file.delete();25 System.out.println("刪除文件:"+file.getName());26 }27 }28 //刪除文件夾29 srcFolder.delete();30 System.out.println("刪除文件夾:"+srcFolder.getName());31 }32 }33 }20.06 IO流概述及分類
IO流用來處理設備之間的數據傳輸
Java對數據的操作是通過流的方式
Java用于操作流的對象都在IO包中
20.07 IO流基類概述按照數據流向:輸入流[讀入數據]、輸出流[寫出數據]
按照數據類型:
字節流字節輸入流[InputStream]、字節輸出流[OutputStream]
字符流字符輸入流[Reader]、字符輸出流[Writer]
注:由這四個類派生出來的子類名稱都是以其父類名作為子類名的后綴
InputStream:此抽象類是表示字節輸入流的所有類的超類。
OutputStream:此抽象類是表示輸出字節流的所有類的超類。
Reader:用于讀取字符流的抽象類。
Writer:寫入字符流的抽象類。
20.08 FileOutputStream的構造方法FileOutputStream的構造方法
public FileOutputStream(File file)throws FileNotFoundException
創建一個向指定 File 對象表示的文件中寫入數據的文件輸出流。
public FileOutputStream(String name)throws FileNotFoundException
創建一個向具有指定名稱的文件中寫入數據的輸出文件流。
20.09 FileOutputStream寫出數據例:
1 FileOutputStream fos = new FileOutputStream("D://a.txt");2 fos.write("hello,IO".getBytes());3 //釋放資源,關閉此文件輸出流并釋放與此流有關的所有系統資源。4 fos.close();創建字節輸出流對象了做了3件事情:
A:調用系統功能去創建文件
B:創建fos對象
C:把fos對象指向這個文件
字節輸出流操作步驟:
A:創建字節輸出流對象
B:寫數據
C:釋放資源
為什么一定要close()
A:讓流對象變成垃圾,這樣就可以被垃圾回收器回收了
B:通知系統去釋放跟該文件相關的資源
20.10 FileOutputStream的三個write()方法FileOutputStream 的方法:
1.public void write(int b)throws IOException
將指定字節寫入此文件輸出流。實現 OutputStream 的 write 方法。
2.public void write(byte[] b)throws IOException
將 b.length 個字節從指定 byte 數組寫入此文件輸出流中。
3.public void write(byte[] b,int off,int len)throws IOException
將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此文件輸出流。
例:
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 FileOutputStream fos = new FileOutputStream("D://a.txt"); 6 //寫一個字節 7 fos.write(97); 8 byte[] bys = {97,98,99,100,101}; 9 //寫一個字節數組10 fos.write(bys);11 //寫一個字節數組的一部分,從1開始寫3個12 fos.write(bys,1,3);13 //釋放資源14 fos.close();15 }16 }文件a.txt中的內容:aabcdebcd
20.11 FileOutputStream寫出數據實現換行和追加寫入public FileOutputStream(String name,boolean append)throws FileNotFoundException
創建一個向具有指定 name 的文件中寫入數據的輸出文件流。如果第二個參數為 true,則將字節寫入文件末尾處,而不是寫入文件開始處。
例:
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 //true表示每次將內容寫到文件的末尾 6 FileOutputStream fos = new FileOutputStream("D://a.txt",true); 7 for (int i = 0; i < 10; i++) 8 { 9 fos.write(("hello"+i).getBytes());10 //寫入換行符,不同系統下的換行符是不一樣的,Windows下為/r/n11 fos.write("/r/n".getBytes());12 }13 //釋放資源14 fos.close();15 }16 }20.12 FileOutputStream寫出數據異常處理
1 public class Practice 2 { 3 public static void main(String[] args) 4 { 5 FileOutputStream fos = null; 6 try 7 { 8 fos = new FileOutputStream("D://a.txt"); 9 fos.write("hello".getBytes());10 } 11 catch (FileNotFoundException e) 12 {13 e.printStackTrace();14 }15 catch(IOException e)16 {17 e.printStackTrace();18 }19 finally20 {21 //fos不是null才close()22 if(fos != null)23 {24 //保證close一定會執行25 try {26 fos.close();27 } catch (IOException e) {28 e.printStackTrace();29 }30 }31 }32 }33 }20.13 FileInputStream讀取數據
FileInputStream的構造方法
1.public FileInputStream(File file)throws FileNotFoundException
通過打開一個到實際文件的連接來創建一個 FileInputStream,該文件通過文件系統中的 File 對象 file 指定。
2.public FileInputStream(String name)throws FileNotFoundException
通過打開一個到實際文件的連接來創建一個 FileInputStream,該文件通過文件系統中的路徑名 name 指定。
FileInputStream的成員方法
1.public int read()throws IOException
從此輸入流中讀取一個數據字節。
2.public int read(byte[] b)throws IOException
從此輸入流中將最多 b.length 個字節的數據讀入一個 byte 數組中。
例:
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 FileInputStream fis = new FileInputStream("D://a.txt"); 6 // //讀一個字節,沒有數據返回-1 7 // int by = fis.read(); 8 // System.out.println((char)by); 9 //循環讀取10 int ch = 0;11 while((ch = fis.read()) != -1)12 {13 //此處如果讀中文會出現亂碼,因為一個漢字占用兩個字節14 System.out.print((char)ch);15 }16 fis.close();17 }18 }20.14 字節流復制文本文件案例(一次讀一個字節)
數據源:從哪里來 a.txt--讀取數據--FileInputStream
目的地:到哪里去 b.txt--寫數據--FileOutputStream
例:
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 // 封裝數據源 6 FileInputStream fis = new FileInputStream("d://a.txt"); 7 // 封裝目的地 8 FileOutputStream fos = new FileOutputStream("d://b.txt"); 9 10 int by = 0;11 while ((by = fis.read()) != -1)12 {13 fos.write(by);14 }15 16 // 釋放資源17 fos.close();18 fis.close();19 }20 }20.15 計算機是如何識別把兩個字節拼接為中文
例:
1 String s = "你好中國";2 byte[] bys = s.getBytes();3 System.out.println(Arrays.toString(bys));
運行結果:
[-60, -29, -70, -61, -42, -48, -71, -6]
上例中在GBK編碼下將"你好中國"轉為字節數組發現數組中的元素都是負數
在計算機中中文的存儲分兩個字節:
第一個字節肯定是負數。
第二個字節常見的是負數,可能有正數。但是沒影響。
20.16 字節流復制圖片案例 1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 FileInputStream fis = new FileInputStream("C://06.jpg"); 6 FileOutputStream fos = new FileOutputStream("D://006.jpg"); 7 8 int by = 0; 9 while((by = fis.read()) != -1)10 {11 fos.write(by);12 }13 14 fis.close();15 fos.close();16 }17 }20.17 FileInputStream讀取數據一次一個字節數組
例:
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 FileInputStream fis = new FileInputStream("D://a.txt"); 6 7 //數組的長度一般是1024或者1024的整數倍 8 byte[] bys = new byte[1024]; 9 int len = 0;//定義一個變量用于接收讀取的字節個數10 while((len = fis.read(bys)) != -1)11 {12 //將數組的一部分轉成字符串,因為數組不一定每次都是讀滿的13 //讀多少數據就轉多少數據14 //不需要換行符15 System.out.print(new String(bys, 0, len));16 17 }18 //釋放資源19 fis.close();20 }21 }20.18 字節流復制文本文件案例(一次讀一個字節數組)
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 //原數據 6 FileInputStream fis = new FileInputStream("D://a.txt"); 7 //目的數據 8 FileOutputStream fos = new FileOutputStream("D://c.txt"); 9 byte[] bys = new byte[1024];10 int len = 0;11 while((len = fis.read(bys)) != -1)12 {13 fos.write(bys, 0, len);14 }15 //釋放資源16 fis.close();17 fos.close();18 }19 }20.19 字節流復制視頻案例
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 //原數據 6 FileInputStream fis = new FileInputStream("C://test.flv"); 7 //目的數據 8 FileOutputStream fos = new FileOutputStream("D://aaa.flv"); 9 byte[] bys = new byte[1024];10 int len = 0;11 while((len = fis.read(bys)) != -1)12 {13 fos.write(bys, 0, len);14 }15 //釋放資源16 fis.close();17 fos.close();18 }19 }20.20 BufferedOutputStream寫出數據
字節流一次讀寫一個數組的速度明顯比一次讀寫一個字節的速度快很多,這是加入了數組這樣的緩沖區效果,java本身在設計的時候,也考慮到了這樣的設計思想(裝飾設計模式),所以提供了字節緩沖區流
字節緩沖輸出流:BufferedOutputStream
字節緩沖輸入流:BufferedInputStream
BufferedOutputStream構造方法:
1.public BufferedOutputStream(OutputStream out)
創建一個新的緩沖輸出流,以將數據寫入指定的底層輸出流。
2.public BufferedOutputStream(OutputStream out,int size)
創建一個新的緩沖輸出流,以將具有指定緩沖區大小的數據寫入指定的底層輸出流。
例:
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 FileOutputStream fos = new FileOutputStream("D://a.txt"); 6 BufferedOutputStream bos = new BufferedOutputStream(fos); 7 //寫數據 8 bos.write("hello".getBytes()); 9 //關閉資源10 bos.close();11 }12 }20.21 BufferedInputStream讀取數據
例:
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream("D://a.txt")); 6 //方式1:讀一個字節 7 int by = 0; 8 while((by = bis1.read()) != -1) 9 {10 System.out.print((char)by);11 }12 System.out.println("------");13 //方式2:讀一個字節數組14 BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream("D://a.txt"));15 byte[] bys = new byte[1024];16 int len = 0;17 while((len = bis2.read(bys)) != -1)18 {19 System.out.println(new String(bys, 0, len));20 }21 22 bis1.close();23 bis2.close();24 }25 }20.22 字節流四種方式復制MP4并測試效率
基本字節流一次讀寫一個字節 //耗時:103891毫秒
基本字節流一次讀寫一個字節數組 //耗時:1110毫秒
高效字節流一次讀寫一個字節 //耗時:1547毫秒
高效字節流一次讀寫一個字節數組 //耗時:953毫秒
1 public class Practice 2 { 3 public static void main(String[] args) throws IOException 4 { 5 long time1 = System.currentTimeMillis(); 6 // method1("C://test.flv","D://test1.flv"); 7 // method2("C://test.flv","D://test2.flv"); 8 // method3("C://test.flv","D://test3.flv"); 9 method4("C://test.flv","D://test4.flv");10 long time2 = System.currentTimeMillis();11 System.out.println("耗時:"+(time2 - time1)+"毫秒");12 }13 //基本字節流一次讀寫一個字節14 //耗時:103891毫秒15 public static void method1(String src,String dest) throws IOException16 {17 FileInputStream fis = new FileInputStream(src);18 FileOutputStream fos = new FileOutputStream(dest);19 20 int by = 0;21 while((by = fis.read()) != -1)22 {23 fos.write(by);24 }25 26 fis.close();27 fos.close();28 }29 //基本字節流一次讀寫一個字節數組30 //耗時:1110毫秒31 public static void method2(String src,String dest) throws IOException32 {33 FileInputStream fis = new FileInputStream(src);34 FileOutputStream fos = new FileOutputStream(dest);35 36 byte[] bys = new byte[1024];37 int len = 0;38 while((len = fis.read(bys)) != -1)39 {40 fos.write(bys,0,len);41 }42 43 fis.close();44 fos.close();45 }46 //高效字節流一次讀寫一個字節47 //耗時:1547毫秒48 public static void method3(String src,String dest) throws IOException49 {50 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));51 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));52 53 int by = 0;54 while ((by = bis.read()) != -1) 55 {56 bos.write(by);57 }58 59 bos.close();60 bis.close();61 }62 //高效字節流一次讀寫一個字節數組63 //耗時:953毫秒64 public static void method4(String src,String dest) throws IOException65 {66 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));67 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));68 69 byte[] bys = new byte[1024];70 int len = 0;71 while ((len = bis.read(bys)) != -1) 72 {73 bos.write(bys, 0, len);74 }75 76 bos.close();77 bis.close();78 }79 }新聞熱點
疑難解答