什么是泛型?
限制容器存储的元素类型,用于集合、接口、实现类中
说明:泛型参数在指明时,不可以使用基本数据类型!不过可以使用包装类替换
案例1:ArrayList
java">ArrayList<Integer> list = new ArrayList<Integer>(); // 或省略后面的Integer ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
// list.add("bb"); // 报错
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {Integer i = iterator.next(); // 使用泛型,此处不再需要强转了System.out.println(i);
}
案例2:HashMap
java">HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("aaa", 12);
map.put("bbb", 13);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator();
while(iterator.hasNext()) {Map.Entry<String, Integer> entry = iterator.next();System.out.println("key:" + entry.getKey() + "\tvalue:" + entry.getValue());
}
案例3:比较器:自然/定制排序
java">class Person implements Comparable<Person>{private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}// ... 此处省略name、age的getter、setter方法// ... 此处省略toString方法public int compareTo(Person p) {return this.age - p.getAge(); // 自然排序:按年龄从小到大排序}
}
class Test {public static void main(String[] args) {ArrayList<Person> list = new ArrayList<>();list.add(new Person("ccc", 19));list.add(new Person("aaa", 18));list.add(new Person("bbb", 19));Collections.sort(list); // 自然排序// 定制排序Collections.sort(list, new Comparator<Person>() {// 先比较年龄(从小到大),年龄一样时比较姓名(从小到大)public int compare(Person p1, Person p2) {int result = p1.getAge() - p2.getAge();if (result != 0) {return result;}return p1.getName().compareTo(p2.getName());}});System.out.println(list);}
}
自定义泛型
说明:
① 在定义类/接口时加上<T>,就表示此类/接口具备了泛型功能
② 类/接口中所有用到的泛型(T)的地方,都会替换成实例化时声明的类型
③ 当一个类继承泛型类时,泛型默认不会继承过来,所以此子类不是个泛型类(需要单独指明泛型),并且父类带泛型的属性默认是Object类型
④ 在静态方法中不能使用泛型,因为在创建对象时才能指明泛型类型
⑤ 异常类不能带泛型
java">class CustomTest<T> {private int id;private T a;public CustomTest() {}public CustomTest(int id, T a) {this.id = id;this.a = a;}public T getA() {return this.a;}public void setA(T a) {this.a = a;}
}
// 情况一:直接继承,子类是不带泛型的,且继承过来的父类泛型默认是Object
class SubCustomTest1 extends CustomTest {}
// 情况二:子类不是泛型类,继承父类时,指明父类泛型的类型是Integer,所以继承过来的属性是Integer
class SubCustomTest2 extends CustomTest<Integer> {}
// 情况三:子类是个泛型,并且指明父类泛型与子类泛型相同
class SubCustomTest3<T> extends CustomTest<T> {}
// 情况四:子类是个泛型,并且指明父类泛型是Integer
class SubCustomTest4<E> extends CustomTest<Integer> {}
// 情况五:指明父类泛型是T,子类泛型是E,不冲突
class SubCustomTest5<T, E> extends CustomTest<T> {}public class Test {public static void main(String[] args) {CustomTest<String> ct = new CustomTest<>();ct.setA("123");// ct.setA(6); // 类型不匹配,报错System.out.println(ct.getA()); // "123"}
}
自定义泛型方法
- 格式:
public <E> E method(E str) {}
- 说明
① 在返回值类型前面加上<E>就表示这是有一个泛型方法
② 在泛型方法调用时,指明泛型类型
③ 泛型方法可以声明static的
④ 泛型方法跟泛型类无关