在之前的文章我們介紹了一下 Java 中的 集合框架中的Collection 的迭代器 Iterator,本章我們來看一下 Java 集合框架中的Collection 的泛型。
在講泛型之前我們先來看下面一段程式碼:
1 public class Main { 2 public static void main(String[] args) { 3 Point point = new Point(1, 2); 4 5 point.setX(2); 6 int ix = point.getX(); 7 System.out.println(ix); // (2, 2) 8 9 /** 10 * 如果想要 x 值變為 double 型別則可以強轉為 double 型別 11 * */ 12 point.setX(2); 13 double dx = (double) point.getX(); 14 System.out.println(dx); // 2.0 15 } 16 } 17 18 class Point { 19 private int x; 20 private int y; 21 22 public Point(int x, int y) { 23 this.x = x; 24 this.y = y; 25 } 26 27 public int getX() { 28 return x; 29 } 30 31 public void setX(int x) { 32 this.x = x; 33 } 34 35 public int getY() { 36 return y; 37 } 38 39 public void setY(int y) { 40 this.y = y; 41 } 42 43 @Override 44 public String toString() { 45 return "(" + x + ", " + y + ")"; 46 } 47 }
上面的程式碼我們之前的文章講過,我們可以通過傳入 x 和 y 值來定義 Point 點,如果我們想要 double 型別的點時需要造型為 double 型別,那我要定義漢字型別的呢?那就造型成 String 型別,這就很麻煩,每次都需要自己來造型,有種鞋不合腳的感覺,那能不能定義我想要什麼型別就是什麼型別呢,如下:
1 public class Main { 2 public static void main(String[] args) { 3 Point<Integer> point1 = new Point<Integer>(1, 2); // 必須是包裝類 4 point1.setX(1); 5 System.out.println(point1.getX()); // 1 6 7 Point<Double> point2 = new Point<Double>(1.1, 2.1); // 必須是包裝類 8 point2.setX(1.2); 9 System.out.println(point2.getX()); // 1.2 10 11 Point<String> point3 = new Point<String>("一", "二"); // 必須是包裝類 12 point3.setX("三"); 13 System.out.println(point3.getX()); // 三 14 } 15 } 16 17 /** 18 * 泛型 19 * 又稱引數化型別,是將當前類的屬性的型別,方法引數的型別及方法 20 * 返回值的型別的定義權移交給使用者, 21 * 使用者在建立當前類的同時將泛型的試劑型別傳入 22 * 數字和字母組合,數字不能開頭 23 */ 24 class Point<T> { // 定義為泛型 T 型別 25 private T x; 26 private T y; 27 28 public Point(T x, T y) { 29 this.x = x; 30 this.y = y; 31 } 32 33 public T getX() { 34 return x; 35 } 36 37 public void setX(T x) { 38 this.x = x; 39 } 40 41 public T getY() { 42 return y; 43 } 44 45 public void setY(T y) { 46 this.y = y; 47 } 48 49 @Override 50 public String toString() { 51 return "(" + x + ", " + y + ")"; 52 } 53 }
從上面的程式碼中,我們定義了一個 T 的型別 Point,當我們要例項化該類時,根據自己的需求傳入想要的包裝類型別即可,這樣就滿足了不同的需求,各取所需。
泛型從底層來說其實就是 Object,定義了泛型只是編譯器在做一些驗證工作,當我們對泛型型別設定值時,會檢查是否滿足型別要求,當我們獲取一個泛型型別的值時,會自動進行型別轉換。
在平時我們是很少自己來定義泛型的,泛型是用來約束集合中元素的型別,如下:
1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Iterator; 4 5 public class Main { 6 public static void main(String[] args) { 7 Collection<String> collection = new ArrayList<String>(); // 只能新增 String 型別的元素 8 collection.add("one"); 9 collection.add("two"); 10 collection.add("thee"); 11 collection.add("four"); 12 // collection.add(1); // 編譯錯誤 13 for (String string : collection) { 14 System.out.println(string); // one two three four 15 } 16 Iterator<String> iterator = collection.iterator(); 17 while (iterator.hasNext()) { 18 // String string = (String) iterator.next(); 不需要再造型 19 String string = iterator.next(); 20 System.out.println(string); // one two three four 21 } 22 } 23 }