什么是泛型:
泛型是JDK1.5引入的一种类型机制,就是将数据类型参数化,作为一种类型安全机制而产生的。
泛型机制就是将类型检查从运行时提前到了编译期,泛型在本质上就是类型的参数化。
泛型的意义:
1、编译期间确定类型,保证类型安全,放的是什么,取的也是什么,不用担心抛出 ClassCastException 异常。
2、提升可读性,从编码阶段就显式地知道泛型集合、泛型方法等处理的对象类型是什么。
3、泛型合并了同类型的处理代码提高代码的重用率,增加程序的通用灵活性。
举个例子:将一个对象放入集合中,集合不会记住这个对象的具体类型,当再次从集合中取出对象时,该对象的编译期类型变成了Object类型,但是其运行时类型仍然为原始的类型。
public static void main(String[] args) {
List list=new ArrayList();
list.add("123");
list.add(123);//集合中不能存放原生类型数据,会涉及自动装箱操作
for(int i=0;i<list.size();i++) {
Object tmp=list.get(i);
Date dd=(Date)tmp;//没有语法报错
System.out.println(dd);//这里需要调用Date类型的getYear方法,所以需要进行窄化操作
}
}
运行时出现:Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.Date
出错的原因:进行强制类型转换之前没有进行类型的判断
public static void main(String[] args) {
List list = new ArrayList();
list.add(new Date());
for (int i = 0; i < list.size(); i++) {
Object tmp = list.get(i);
if (tmp != null && tmp instanceof Date) {
Date dd = (Date) tmp;
System.out.println(dd.getYear()+1900);//2022
}
}
}
泛型:可以将运行时的类型检查搬到编译期实现,直接获取指定类型数据避免强制类型转换操作。
泛型类
泛型类也叫做参数化类型,就是具有一个或者多个类型参数的类,一个泛型类可以有多个泛型声明,所有的泛型 声明都应该在<>内部。
在当前类中 T 就是一个类型的说明,可以用在说明任何实例方法中的局部变量、方法的形参以及方法的返回值, 类的成员变量;但是类型 T 不能直接使用在静态方法中。
Comparable和Comparator接口
Comparable:
如果一个类实现了 Comparable 接口,则表示当前类型的对象是可比较大小的,也就是说可以进行排序。
实现了 Comparable 接口的类支持排序,也就是可以使用工具类 Collections 对集合对象进行排序
Comparator:
Comparator 是比较器接口。如果类本身不支持排序比较,即实现 Comparable 接口,则可以建一个类型的比较 器专门用于排序比较。
Comparable和Comparator接口比较:
Comparable 接口是排序接口,如果一个类实现了 Comparable 接口就意味着该类型的对象是可比较的;
而 Comparator 接口是比较器,如果需要控制某个类的次序,可以临时建议一个该类的比较器进行排序;
可以将 Comparable 当作内部比较器,而 Comparator 相当于外部比较器
泛型和Comparable接口的基础使用:
public class BubbleSort<T extends Comparable<T>> {
public void sort(List<T> list) {
for(int i=1;i<list.size();i++) {
for(int k=0;k<list.size()-i;k++) {
if(list.get(k).compareTo(list.get(k+1))>0) {
T tmp=list.get(k);
list.set(k, list.get(k+1));
list.set(k+1, tmp);
}
}
}
}
}
测试类:
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
Random r = new Random();
for(int i=0;i<10;i++) {
list.add(r.nextInt(1000));
}
for(int i=0;i<10;i++) {
System.out.print(list.get(i)+"\t");
}
System.out.println();
BubbleSort<Integer> bs=new BubbleSort<>();
bs.sort(list);
for(int i=0;i<list.size();i++) {
System.out.print(list.get(i)+"\t");
}
}
//输出结果(不唯一)
786 734 188 474 675 843 910 987 550 598
188 474 550 598 675 734 786 843 910 987