Java 從入門到進階之路(二十三)

豐寸發表於2020-06-17

在之前的文章我們介紹了一下 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 }

  

相關文章