开启新的征程,数据结构:泛型
1:在Java中,由于基本数据类型不是继承自Object类,为了在泛型代码中可以支持基本数据类型,Java给每个基本数据类型都对应了一个包装类型。
2:装箱:将基本数据类型转化为包装类型(自动装箱、显示装箱)
输出结果:
3:拆箱:将包装类型转换为基本数据类型(自动拆箱、显示拆箱)
输出结果:
4:Integer数据类型的取值范围为:-128-127
下面是曾经的一道阿里的面试题,猜想下面的输出结果:
a和b的值在-128到127之间,Java会使用缓存,即对于相同的小范围整数值,会从缓存中获取相同的Integer对象,因此a和b实际上是同一个对象,“==”比较的是对象的应用,因此输出“true”。
c和d的值超过了127,自动装箱时不会使用缓存,会创建不同的Integer对象,因此c和d是不同的对象,这里输出“false”。
输出结果:
5:引出泛型:实现一个类,类中包含一个数组成员,使得数组中可以放任何类型的数据,也可以根据成员方法返回某个数组下标的值。
创建一个Object类型的数组array,给出一个set和get方法,set方法将pos位置的数组值设置为val,get方法用于返回pos位置的数组值,类型为Object。
创建一个集合myArray,用set方法在0和1位置输入值。
但观察第8、9和第15、16行代码,每次调用get方法都要强制类型转换后再赋值打印,这样未免太过麻烦,为了简便,采用泛型的写法。
输出结果:
应用泛型:
<T>代表当前类是一个泛型类。
将set方法中的设置值的val的类型设置为T,把get方法的返回值类型设置为T,将array[pos]的类型强制转换为T。
创建一个myArray集合,并指定里面存储的对象是Integer类型。
创建一个myArray2集合,并指定里面存储的对象是String类型。
再用set方法设置想输入的值,最后调用get方法时就不用再进行强制类型转换,直接赋值并输出结果。
输出结果:
6:不能new泛型类型的数组,要用Object类型
7:尖括号里必须存放包装类型,不能存放基本数据类型
8:擦除机制:在编译过程中,将所有的T替换为Object,最后运行过程中都是Object类型。
9: 泛型的上界:(这里extends是扩展的意思)
语法:class 泛型类名称<类型形参 extends 类型边界>{
}
实例:public class <E extends Number>,E必须是Number的子类
MyArray<Integer> I1,编译正确,Integer是Number的子类
MyArray<String> I2,编译错误,String不是Number的子类
示例:E实现Comparable接口,找数组最大值
1:定义了一个Alg类,T实现了Comparable<T>接口,然后给出了一个findMax方法,返回值类型为T,用于找到数组中的最大值,参数类型为T类型的数组。
初始指定数组的第一个元素为最大值,然后通过for循环遍历数组,同时调用compareTo方法,如果结果大于0,则第i个数组元素大于max,将这个值赋给max。最后返回最大值max。
2:定义了一个测试类Test3,在main方法中,实例化了一个Alg类,指定泛型类型为Integer。
然后给出了一个Integer类型的数组(打乱顺序),最后调用findMax方法并将最大值赋值给ret,最后打印ret。
3:输出结果:
10:泛型方法
语法:方法限定符<类型形参列表> 返回值类型 方法名称(形参列表){....}
示例:通过findMax方法获取数组最大值
1:此时不再是一个泛型类,而是一个泛型方法,此后的代码语法都和上面一样。
2:在测试类Test3和main方法中,实例化了一个Alg类,不过此时不再需要指定一个泛型类型Integer,因为类不再是泛型类。此时的代码和上述一样。
3:输出结果: