通配符解释(PECS原则)

什么是泛型

泛型是带有参数的类型。在 Java 中,容器类允许你指出其内部对象的类型。
声明泛型变量时,我们指出两个(而不是一个)类型:变量类型和它所存储的数据的类。
Java1.7开始允许在创建对象时不写泛型类型,例如 **Collection<String> coll = new ArrayList<>()**
泛型 - 图1

“ArrayList 是一个很好的示例。创建新的 ArrayList 对象时,可以方便地指出将在此列表内存储的值的类型。”

代码 说明
ArrayList<String> list = new ArrayList<String>(); 创建名为 list的 ArrayList 变量。
将 ArrayList 对象分配给该变量。
此列表只能存储 String 对象。
ArrayList list = new ArrayList(); 创建名为 list的 ArrayList 变量。
将 ArrayList 对象分配给该变量。此列表可以存储任意值。
ArrayList<Integer> list = new ArrayList<Integer>(); 创建名为 list的 ArrayList 变量。
将 ArrayList 对象分配给该变量。
此列表只能存储 Integerint值。

泛型方法定义

  1. public static <K,V> V get(Map61B<K,V> map, K key) {
  2. if map.containsKey(key) {
  3. return map.get(key);
  4. }
  5. return null;
  6. }
  7. public static <K extends Comparable<K>, V> K maxKey(Map61B<K, V> map) {
  8. List<K> keylist = map.keys();
  9. K largest = map.get(0);
  10. for (K k: keylist) {
  11. if (k.compareTo(largest)) {
  12. largest = k;
  13. }
  14. }
  15. return largest;
  16. }

例子:

  1. import java.util.ArrayList;
  2. import java.util.Iterator;
  3. import java.util.List;
  4. public class ArraySet<T> implements Iterable<T> {
  5. private int size; // the next item to be added will be at position size
  6. private T[] items;
  7. public ArraySet() {
  8. items = (T[]) new Object[100];
  9. size = 0;
  10. }
  11. /*
  12. * Returns true if this map contains a mapping for the specified key.
  13. */
  14. public boolean contains(T x) {
  15. for (int i = 0; i < size; i += 1) {
  16. if (items[i].equals(x)) {
  17. return true;
  18. }
  19. }
  20. return false;
  21. }
  22. /*
  23. * Associates the specified value with the specified key in this map.
  24. * Throws an IllegalArgumentException if the key is null.
  25. */
  26. public void add(T x) {
  27. if (x == null) {
  28. throw new IllegalArgumentException("can't add null");
  29. }
  30. if (contains(x)) {
  31. return;
  32. }
  33. items[size] = x;
  34. size += 1;
  35. }
  36. /* Returns the number of key-value mappings in this map. */
  37. public int size() {
  38. System.out.println(this);
  39. return size;
  40. }
  41. /** returns an iterator (a.k.a. seer) into ME */
  42. public Iterator<T> iterator() {
  43. return new ArraySetIterator();
  44. }
  45. private class ArraySetIterator implements Iterator<T> {
  46. private int wizPos;
  47. public ArraySetIterator() {
  48. wizPos = 0;
  49. }
  50. public boolean hasNext() {
  51. return wizPos < size;
  52. }
  53. public T next() {
  54. T returnItem = items[wizPos];
  55. wizPos += 1;
  56. return returnItem;
  57. }
  58. }
  59. @Override
  60. public String toString() {
  61. List<String> list = new ArrayList<>();
  62. for (T t : this) {
  63. list.add(t.toString());
  64. }
  65. return String.join(", ", list);
  66. }
  67. public static <E> ArraySet<E> of(E... e) {
  68. ArraySet<E> returnSet = new ArraySet<>();
  69. for (E x : e) {
  70. returnSet.add(x);
  71. }
  72. return returnSet;
  73. }
  74. @Override
  75. public boolean equals(Object other) {
  76. if (this == other)
  77. return true;
  78. if (other == null)
  79. return false;
  80. if (this.getClass() != other.getClass())
  81. return false;
  82. ArraySet<T> o = (ArraySet<T>) other;
  83. if (o.size != this.size)
  84. return false;
  85. for (T x : this) {
  86. if (!o.contains(x))
  87. return false;
  88. }
  89. return true;
  90. }
  91. public static void main(String[] args) {
  92. ArraySet<Integer> aset = new ArraySet<>();
  93. aset.add(5);
  94. aset.add(23);
  95. aset.add(42);
  96. // iteration
  97. for (int i : aset) {
  98. System.out.println(i);
  99. }
  100. // toString
  101. System.out.println(aset);
  102. // equals
  103. ArraySet<Integer> aset2 = new ArraySet<>();
  104. aset2.add(5);
  105. aset2.add(23);
  106. aset2.add(42);
  107. System.out.println(aset.equals(aset2));
  108. System.out.println(aset.equals(null));
  109. System.out.println(aset.equals("fish"));
  110. System.out.println(aset.equals(aset));
  111. System.out.println(ArraySet.of("Hi", "I'm", "zdkk"));
  112. }
  113. }