集合不管是接口还是类,定义的时候都使用了泛型
为什么要有泛型?
泛型:一定程度上可以理解为标签
在用泛型之前
ArrayList用add方法,可以放Object类型的数据,可以说这么做并不好,类型就不严格了,用泛型之后就可以限制它的类型,其他数据类型就不能往里面放了
此时把元素的类型设置成一个参数,这个类型参数叫做泛型,
< E >就是类型参数,就是泛型,造对象的时候指明E到底是什么类型,E表示的是类型
当集合中没有用泛型时,任何类型都可以添加到集合中,类型不安全,读取出来的对象需要强转,比较繁琐
集合中使用泛型之前:
public class Test01 {
public static void main(String[] args) {
ArrayList list=new ArrayList();
//需求:存放学生的成绩
list.add("Tom");//类型不安全
for(Object obj:list){
int score=(Integer)obj;//强制类型转换时,会出现类型装换异常
System.out.println(score);
}
}
}
所以要在集合中使用泛型,在添加时可以做类型的检查
E不能是基本数据类型
public class Test01 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(123);
list.add(456);
// 方式一
// for(Integer score:list){
// int stuScore=score;//避免了强转操作
// System.out.println(stuScore);
// }
//方式二
Iterator<Integer> iterator = list.iterator();//Iterator<E>是这样声明的,这是能带<Integer>的前提,如果声明的时候没带泛型,是不能这么用的
//因为实例化的时候ArrayList的是Integer,所以这里是<Integer>
while(iterator.hasNext()){
Integer next = iterator.next();
int subSore=next;
System.out.println(subSore);
}
}
}
如果试图add别的类型,在编译时就会进行类型检查,保证数据的安全,编译的时候就过不去,
可以在方法中,或者是属性中,乃至构造器当中使用类或者接口的泛型,当进行实例化类或者接口的时候,用到泛型的位置都变成指定类型
public class Test01 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();//因为声明的时候写了两个
map.put("Tom",87);
map.put("Jerry",87);
map.put("Jack",67);
//泛型的嵌套
Set<Map.Entry<String, Integer>> entry1 = map.entrySet();//返回的是Set<Entry<String,Integer>>//Entry因为没有直接对外暴露,所以写成Map.Entry
//Entry是内部的接口,是定义在Map里面的,如果想直接写成Entry,需要在上面import java.util.Map.*
Iterator<Map.Entry<String, Integer>> iterator = entry1.iterator();
while(iterator.hasNext()){
Map.Entry<String, Integer> entry = iterator.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"------>"+value);
}
}
}
在集合中使用泛型总结:
1)集合接口和集合类在JDK5.0时都修改为带泛型的结构
2)实例化集合类时,可以指明具体的泛型类型
指明完以后,在集合类或者接口中凡是定义类或者接口时,内部结构使用到类的泛型的位置,都指定为实例化的泛型类型
比如:add(E e)–>add(Integer e)
注意:泛型的类型必须是类,不能是基本数据类型,需要用到基本数据类型的位置,拿包装类替换
如果实例化时,没有指明泛型的类型,默认类型为Object类型
Comparator也有泛型
Comparable也有泛型
public class Employee implements Comparable<Employee>
比如我们想比较的是Employee的name,即按照name进行排序,就写上Employee
就不用像原来那样在compareTo方法中用instanceof进行类型判断了
也不用再进行强制类型装换了
public class Test01 {
public static void main(String[] args) {
TreeSet<Employee> employees = new TreeSet<>(new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
return 0;
}
});
}
}