引入
为什么要使用泛型程度设计
- 泛型程序设计意味着编写的代码可以被很多不同的类型的对象所重用。
- 使代码具有更好的可读性。
例如:一看就可以知道这个数组列表中包含的是String对象。
ArrayList<String>` files = new ArrayList<>();
- 编译器可以很好地利用这一信息,当调用get的时候,不需要进行强制类型转换。
- 使程序有更好的安全性。
例如在add新的元素时,如果加入的元素类型不是String类型,时无法通过编译的。编译错误比类在运行时出现类的强制类型那个转换异常要好的多。
定义简单的泛型类
public class Point<T> {
private T x;
public T getX() {
return x;
}
public Point(T x) {
this.x = x;
}
}
Point类引入了类型变量T,用尖括号(<>)括起来,并放在类名后面。
注意:
1.泛型类可以有多个类型变量。例如,可以定义Point类,其中第一个域和第二个域使用不同的类型。
public class Point<T U> {...}
2.其中泛型中变量(x)的个数定义根据情况而定,如果最后要返回的元素个数有两个,就可以在Point类中再定义一个变量y。
用途:
用具体的类可以替换类型变量就可以实例化泛型类型。如:Point< String>,可以将结果想象成带有构造器的普通类。
泛型方法
不仅可以定义一个泛型类,还可以定义泛型方法。其中,类型变量放在修饰符的后面。
实例:
(求泛型数组中的最小值)
1.定义一个Person.java类
public class Person implements Comparable<Person> {
private String name = "小明";
public void print(){
System.out.println(this.name);
}
public Person(){
}
public Person(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int compareTo(Person p){
if(this.name.compareTo(p.name) <0){
return -1;
}else if(this.name.compareTo(p.name) >0){
return 1;
}else{
return 0;
}
}
@Override
public String toString() {
return this.name;
}
}
注意:要想将自己定义的类实现加入集合或者泛型数组时实现排序,必须继承Comparable接口,并重写其中的compareTo方法。
2.泛型数组求最小值
public class CompareTest2 {
public static void main(String[] args) {
Person p1 = new Person("wang" );
Person p2 = new Person("li");
Person p3 = new Person("zhang");
Person[] ps = {p1,p2,p3};
Person pii = ArrayAlgg.min(ps);
System.out.println(pii);
}
}
class ArrayAlgg{
public static <T extends Comparable> T min(T[] a){
if(a == null || a.length == 0)
return null;
T smallest = a[0];
for(int i =1;i<a.length;i++){
if(smallest.compareTo(a[i])>0)
smallest = a[0];
}
return smallest;
}
}
注意:由于T可以代表任何类型的对象,这个对象可能实现了Comparable接口,也可能没有。所以,这里需要对T进行类型限制,即:
public static <T extends Comparable> T min(T[] a)...
!!限定类型的写法:
<T exends BundingType>
T和绑定类型可以是类,也可是接口。选择关键字extends是因为更接近子类的概念。