Featured image of post Java筆記(1)泛型、集合與檔案操作

Java筆記(1)泛型、集合與檔案操作

惡補Java基礎:)

泛型(Generics)

  • 泛型是多型(polymorphism)的一種技巧
  • 當編譯期間無法確定程式碼的撰寫方式,而是依照執行期間的狀況而決定
  • 不用因為資料型別的限制而實作多種方法,只需要一種方法即可
  • 定義「安全的」泛型類別(Genericsclass),泛型提供編譯時期檢查

泛型用<參數(自定義)>表示,也可以像一般變數一樣傳進多個參數進去,

泛型通常最常使用的情況是,當不確定使用的參數的時候,不用因為資料型別的限制而實作許多方法。

public class Foo<T>{
  private T f;
}
public class Foo<T1,T2>{
  private T1 fl;
  private T2 f2; 
}

通配字元(Wildcard)

  • 共變性
  • 繼承於List的子類別或實作List介面的類別
  • List的父類別
  • 通配字元(?)不能當作宣告方法的型別,必須是變數名稱

使用方式比泛型<>多了一個?

使用範例:

Doo<? extends List >  // 代表?的類別必須是繼承於List的子型別或是實作List介面的類別
Doo<? super List >    //必須是List的父類別
Foo<? extends List> fooObj = new Foo<ArrrayList>(); //因為ArrayList是List子型別,才可以這樣使用。

Foo<? super ArrayList> fooObj = new Foo<List>(); //代表要是Array的父類別才可以使用

ArrayList
ArrayList

集合(COLLECTIONS)

  • 將許多同⼀種資料型態的物件集合在⼀起
  • 比陣列更有彈性好處理

List(有序集合)

  • 將物件依序存放,並依序取出
  • 可以存放重複的物件

官方API文件:https://docs.oracle.com/javase/8/docs/api/java/util/List.html

可以看到了副類別是Collection,且用了泛型Interface List<E>

常用方法:

返回值 說明
boolean add(E e)將指定元素加到此列表的尾端
void add(int index, E element)在此列表中的指定位置插入指定元
void clear()刪除所有元素。
boolean contains(Object o)如果此列表包含指定元素,則返回true 。
boolean isEmpty()如果此列表不包含任何元素,則返回true 。
int size()返回此列表中的元素數。
E get(int index)返回列表中指定位置的元素。
E remove(int index)移除指定位置的元素

練習:

public class TestDemo {

	public static void main(String[] args) {
		String str1 = "test1";
		String str2 = "test2";
		String str3 = "test3";
		
		List<String> list = new ArrayList<String>();
		list.add(str1);
		list.add(str1);
		list.add(str2);
		list.add(str3);
		
		
    //下面進行遍歷
		for(String s : list){
			System.out.println(s);
		}
		
	}

}

結果:

test1
test1
test2
test3

Set(無序集合)

  • 不依序存放物件
  • 存放物件不可以重複

也因為他是無序的關係,導致了存放物件不可重複,也比List少了幾個方法,例如get。

public class TestSetDemo {
	
	public static void main(String[] args){
		Set<String> set  = new HashSet<String>();
		set.add("test1");
		set.add("test2");
		set.add("test3");
		
		set.remove("test2");
		System.out.println(set.size());

	}
}

//執行結果:2

Map

API:https://docs.oracle.com/javase/8/docs/api/java/util/Map.html

  • 將物件以key, value的儲存⽅式,放置於Map物件中
  • 使⽤key取得存放的物件
  • 資料的操作都是透過Key操作
Map(key, value)

範例:

Map<String, Integer> map =new HashMap<String, Integer>();
public class TestMapDemo {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("test1", 1);
		map.put("test2", 2);
		map.put("test3", 3);
		
		System.out.print(map.get("test2"));
    //執行結果:2
		map.remove("test2");

		for(String key : map.keySet()){
			System.out.println(map.get(key));
		}
		//執行結果:3 1
	}

}

JAVA I/O

https://docs.oracle.com/javase/7/docs/api/java/io/File.html

檔案操作

File file = new File(fileName); //fileName路徑名稱
file.mkdir(); //建立檔案
file.mkdirs(); //建立檔案,如果路徑上沒有資料夾會一起建立
file.list(); //讀取目錄
file.delete(); //刪除檔案

建立IOUtil工具類例子:

public class IOUtil {
	
	public static void createFolder(String fileName){ //路經參數,所以如果要在home資料夾新增test資料夾,就要傳進"/home/test"
		File file = new File(fileName);
		file.mkdirs();
	}
	
	public static String[] readFolder(String fileName){ //回傳資料夾下面有哪些檔案
		File file = new File(fileName);
		return file.list();
	}
	
	public static void deleteFolder(String fileName){ //刪除檔案
		File file = new File(fileName);
		file.delete();
	}
}

讀取檔案內容

讀取文字檔

  • FileReader: 以Char, String的⽅方式讀取檔案
  • BufferedReader:BifferedReader有一個建構子,就是放入FileReader之後其他任務就可以交由BifferedReader處理。
  • BufferedReader.readLine():透過readLine()讀取文字,readLine()會回傳String
public class IOUtil {	
  public static void readTxtFile(String fileName) {
      FileReader fr = null;
      try {
        fr = new FileReader(fileName); //1.新增FileReader
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }

      BufferedReader br = new BufferedReader(fr); //2.FileReader交給BufferedReader
      String tmp = null;
      try{
        while((tmp = br.readLine()) != null){ //讀取到沒有資料為止
          System.out.println(tmp); //讀出來的資料會放在tmp一行一行列印出來
        }
      }catch(IOException e){
        e.printStackTrace();
      }finally{   //在IO裡面,要關掉IO,所以在最後關閉
        try {
          br.close();
        } catch (IOException e) { 
          e.printStackTrace();
        }
      }
}

寫入文字檔案

寫入文字檔

  • FileWriter:確認檔案寫入的位置
  • BufferedWriter
    1. BufferedWriter. write(String str):將字串寫進去
    2. BufferedWriter. newLine():跳行
public class IOUtil {
  public static void writeTxtFile(String fileName,List<String> list){
      try {
        FileWriter fw = new FileWriter(fileName);
        BufferedWriter bw = new BufferedWriter(fw);
        for(String str : list){
          bw.write(str);
          bw.newLine(); //繼續往下寫
        }
        bw.flush(); //將記憶體裡面的資料清空
 /*BufferedWriter是緩衝輸入流,意思是調用BufferedWriter的write方法時候。數據是先寫入到緩衝區裡,並沒有直接寫入到目的文件裡。必須用BufferedWriter的flush()方法。這個方法會刷新一下該緩衝流,也就是會把數據寫入到目的文件裡。或者你可以調用BufferedWriter的close()方法,該方法會在關閉該輸入流之前先刷新一下該緩衝流。也會把數據寫入到目的文件裡。原文链接:https://blog.csdn.net/appleml/article/details/41721365*/
      } catch (IOException e) {
        e.printStackTrace();
      } 
    }

    public static void copyPictureFile(File source, File dest){
      FileInputStream fis = null;
      FileOutputStream fos = null;
      try{
        fis = new FileInputStream(source);
        fos = new FileOutputStream(dest);

        byte[] buffer = new byte[1024];
        int off = 0;
        int len = 0;

        while((len = fis.read(buffer)) != -1){
          fos.write(buffer, off, len);
        }
        fos.flush();
      }catch(IOException e){
        e.printStackTrace();
      }finally{
        try {
          fis.close();
          fos.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
}

FileInputStream & FileOutputStream

前面介紹的FileReader以及FileWriter都是透過字串類型來讀取或寫入內容,而FileInputStream & FileOutputStream是透過Byte來做讀取以及寫入

  • FileInputStream read(byte[] b):read(讀進來的byte陣列)
  • FileOutputStream
    1. write(byte[] b, int off, int len) :write(將讀進來的byte陣列,起始位置,長度)
    2. flush():寫入
public class IOUtil {
    public static void copyPictureFile(File source, File dest){ //讀取圖檔
      FileInputStream fis = null; 
      FileOutputStream fos = null;
      try{
        fis = new FileInputStream(source); //取得資料位置
        fos = new FileOutputStream(dest);  //寫入位置

        byte[] buffer = new byte[1024]; //暫存(可以設定更高)
        int off = 0; //起始位置
        int len = 0; 	//長度

        while((len = fis.read(buffer)) != -1){ //長度= -1代表讀取結束
          fos.write(buffer, off, len); //寫入檔案
        }
        fos.flush(); //將緩存寫入
      }catch(IOException e){
        e.printStackTrace();
      }finally{
        try {
          fis.close();
          fos.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
}

IOUtil實作

結合了上面的完成了較實用的Util類別,檔案目錄結構如下,post.txt要自己隨便加個內容

檔案目錄結構
檔案目錄結構

public class IOUtil {
	
	public static void createFolder(String fileName){
		File file = new File(fileName);
		if(file.mkdirs()){
			System.out.println("新建檔案成功");
		}else{
			System.out.println("新建檔案失敗,檔案有可能已存在");
		}
	}
	
	public static String[] readFolder(String fileName){
		try {
			File file = new File(fileName);
			return file.list();
		} catch (NullPointerException exception) {
			exception.printStackTrace(); //把拋出的expection 全部印出來
		} 
		return null;
	}
	
	public static void deleteFolder(String fileName){
		File file = new File(fileName);
		if(file.delete()){
			System.out.println("刪除檔案成功");
		}else{
			System.out.println("刪除檔案失敗,檔案有可能不存在");
		}
	}
	
	public static List<String> readTxtFile(String fileName) {
		FileReader fr = null;
		List<String> list = new ArrayList<>();
		try {
			fr = new FileReader(fileName);
		} catch (FileNotFoundException e) {
			System.out.println("找不到檔案");
			e.printStackTrace();
			return null;
		}
		
		BufferedReader br = new BufferedReader(fr);
		String tmp = null;
		try{
			while((tmp = br.readLine()) != null){
				list.add(tmp);
			}
		}catch(IOException e){
			e.printStackTrace();
		}finally{
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
		
	}
	
	public static void writeTxtFile(String fileName,List<String> list){	
		try {
			FileWriter fw = new FileWriter(fileName);
			BufferedWriter bw = new BufferedWriter(fw);
			
			for(String str : list){
				bw.write(str);
				bw.newLine();
			}
			bw.flush();
      bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		} 
				
	}
	
	public static void copyPictureFile(File source, File dest){
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try{
			fis = new FileInputStream(source);
			fos = new FileOutputStream(dest);
			
			byte[] buffer = new byte[1024];
			int off = 0;
			int len = 0;
			
			while((len = fis.read(buffer)) != -1){
				fos.write(buffer, off, len);
			}
			fos.flush();
			
		}catch(IOException e){
			e.printStackTrace();
		}finally{
			try {
				fis.close();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
}

測試程式:

public static void main(String[] args) {

		String fileName = "./testFolder";
		//建立資料夾
		IOUtil.createFolder(fileName);
	
		//讀取資料夾目錄
		// "../"代表當前目錄前前一級 "./代表目前目錄得前一級"
	    String[] files = IOUtil.readFolder("./codegym");
		for(String name : files){
			System.out.println(name);
		}
		//刪除檔案
		//IOUtil.deleteFolder(fileName);
		//System.out.println("deleteFolder(fileName)執行結束");
		
		//檔案讀取
		List<String> list= IOUtil.readTxtFile("./codegym/post.txt");
		for(String str : list){ //遍歷
			System.out.println(str);
		}
	
		//檔案寫入
		IOUtil.writeTxtFile(fileName + "/textpost.txt",list);
		
		
		//複製圖片
		String source = "./codegym/testImg.png";
		String dest = fileName + "/textImg.png";
		IOUtil.copyPictureFile(new File(source), new File(dest));
		}

完成結果:

終端機輸出:

新建檔案成功
.DS_Store
TestDemo.java
IOUtil.java
post.txt
testImg.png
今天清晨持續受大陸冷氣團影響,各地天氣偏冷,西半部及東北部低溫普遍約11至14℃,其中新竹到雲林、南投及金門有局部10℃以下低溫發生機率,氣象局針對9縣市發布低溫特報。今晨最低溫在嘉義嘉義9.6℃,雲林10℃、彰化、苗栗10.3℃。


中央氣象局預報員張承傳指出,今清晨受大陸冷氣團影響,各地天氣偏冷,西半部及東北部低溫普遍約11至14℃。白天起冷氣團稍微減弱,不過溫度回升幅度不多,北部及東北部高溫只有15至18℃,其他地區20至24℃;基隆北海岸及東北部降雨機率偏高,仍容易有短暫雨,而花東及大台北也偶有零星降雨。

張承傳指出,明天下半天鋒面接近,西半部水氣增多,明晚到周二清晨降雨最明顯,全台都有陣雨機率,周二白天降雨逐漸趨緩,轉為迎風面北部、東北部為主。


周二東北季風增強,屆時北台灣再轉涼,高溫剩下16、17℃。這波東北風從周二影響至周四,不過周三、四水氣較少,僅東半部及北部山區有局部短暫雨,其他地區多雲到晴。周五、周六東北季風減弱,北台灣溫度回升。

中央大學大氣系兼任副教授吳德榮在「三立準氣象· 老大洩天機」專欄撰文指出,今晨強冷空氣及「輻射冷卻」加成,本島平地最低氣溫出現在中部:嘉義民雄鄉9.6℃,雲林虎尾、斗南鎮10℃。今晨迎風面雲層仍多,北海岸、東北部有局部降雨,大台北東側則有零星少量飄雨。

最新模式模擬顯示,今日白天起強冷空氣稍減弱、氣溫微升,北台偏冷、中南部白天舒適晚仍偏冷;桃園以南晴時多雲,北海岸、大台北東側及東半部偶有零星降雨。今日各地氣溫:北部11至17℃,中部10至24℃,南部11至26℃,東部12至24℃。

執行後檔案目錄結構:

執行後目錄結構
執行後目錄結構

comments powered by Disqus