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