如果要针对每种类型的对象写一个数据结构,则当需要将其运用到其他对象上时,还要重写这个数据结构。如果使用了Object这个类型,编写的数据结构虽然通用性很好,但是不能保证传出对象的安全性。从这就可看出,泛型的存在是必要的。
1.为什么使用泛型?
1.限制保存的元素类型,不需要强制转换。
2.保证传入对象的安全
代码示例:
//定义参数类型为T的类:
public class Stack{
private LinkedList con = new LinkedList();
//向栈中添加元素
public void push(T t){
con.addFirst(t);
}
//从栈中删除元素
public T pop(){
return con.removeFirst();
}
public boolean empty(){
return con.isEmpty();
}
}
测试类:
public class StackTest{
public static void main(String[] args){
//在创建栈时就指明只能保存字符串类型
Stack stackStr = new Stack();
//在创建栈时就指明只能保存整型
Stack stackInt = new Stack();
stackStr.push("java好美");
stackInt.push(1);
while(!stackStr.empty()){
System.out.println((String)stackStr.pop());
}
while(!stackInt.empty()){
System.out.println((int)stackInt.pop());
}
}
}
2.泛型化数组
java虚拟机中并没有泛型类型的对象,不支持实例化对象,如T[]array = new T[10];在java中是非法的。那么在自定义数据结构时,我们需要使用泛型数组怎么办?当然是使用反射机制。Array类中的newInstance()方法可以根据指定的类型和长度创建一个数组。
代码:
//定义一个参数类型为T的类
public class A{
//声明一个类型为T的数组
private T[] array;
//用于保存数组长度
private int size;
//初始化数组长度和创建泛型数组
public A(Class type,int size){
this.size = size;
array = (T[])Array.newInstance(type,size);
}
}
测试类:
public class TestA{
pubic static void main(String[] args){
//创建了一个长度为10,字符串类型的数组
A a = new A(String.class,10);
}
}
3.泛型的局限性
1.不能使用基本类型作为其类型参数,只能是Class
2.不能抛出或捕获泛型类型的实例
3.不能直接使用泛型数组
4.不能实例化类型变量
4.静态泛型方法
在java中不仅可以声明泛型类,也可以在普通类中声明泛型方法,但是要注意以下几点:
1.使用格式来表示泛型类型参数,参数的个数可以不是一个
2.类型参数列表要放在访问修饰符、static、和final之后
3.类型参数要放在返回值类型、方法名称、方法参数之前
例如:
public static List query(String s,Class type){}
注意:
在使用泛型类时,不能将泛型参数类用于静态域和静态方法中。而对于静态泛型方法是可以的。这是泛型类与泛型方法的重要区别。因为泛型方法使用已经指明了参数的具体类型。
5.将T限制为某一个类的实现类
例如:将T限制为实现Comparable接口的实现
<T extends Comparable>
6.定义泛型接口
接口声明如下:
public interface Max<T extends Comparable<T>>
其实现类的声明如下:
public class Comparison<T extends Comparable> implements Max<T>
7.使用通配符增强泛型
<? extends Number>表示Byte、Double等都适合这个类型参数
<? super Number>表示类型参数是Number类的父类,如Object
代码:
public class Test {
//获取中间值
public static Object getMiddle(List list){
return list.get(list.size()/2);
}
public static void main(String[] args) {
//整型
List ints = new ArrayList();
ints.add(1);
ints.add(2);
ints.add(3);
//Double类型
List doubles = new ArrayList();
doubles.add(1.1);
doubles.add(2.2);
doubles.add(3.3);
System.out.println(getMiddle(ints));
System.out.println(getMiddle(doubles));
}
}
8.利用泛型实现折半查找
只需要将int替换成泛型类型T就可以实现更加通用的算法
public class BinSearch190 {
public static > int search(T[] array,T key){
int low = 0;
int mid = 0;
int high = array.length;
while(low<= high){
mid = (low+high)/2;
System.out.println(mid+"");
if(key.compareTo(array[mid])>0){
low = mid+1;
} else if(key.compareTo(array[mid])<0){
high = mid - 1;
} else {
System.out.println();
return mid;
}
}
return -1;
}
public static void main(String[] args) {
Integer[] ints = {1,2,3,4,5};
System.out.println("元素3所对应的索引号"+search(ints,3));
}
}