1. 泛型的作用
泛型,是在创建集合对象时就规定其允许保存的元素类型,然后由编译器负责检查所要添加元素的合法性,另外在取用元素时就不必再进行强制性的类型转换处理。即:将原本确定不变的类型参数化。JDK5.0提出了泛型的概念,通过使用泛型写出更为通用的程序代码。
2. 泛型的用法
泛型分为:泛型类、泛型方法、泛型接口。
泛型类:在类名的后面用尖括号括起一个(或多个)类型参数。(注:类型参数的作用域是定义这个类型参数的整个类,但不包括静态成员方法。因为其类型参数不定,无法直接分配储存空间)
泛型方法:在方法的返回类型前面加上一个类型参数T,并有<>括起来。
泛型接口:在借口名之后加上类型参数。
(下面用常用的泛型接口举例说明Comparablej接口和Comparator接口,通过实现借口中的方法来自定义Collections.sort()和Arrays.sort()的排序规则)
3. 泛型应用举例(Comparator和Comparable接口)
1、泛型类、泛型方法的应用实例
package xcu.hl.fanxing;
import java.util.List;
/**
* 1、泛型类的使用 就是在类名后面加上<T> 多个类型参数时用 ,分隔
* 2、泛型方法的使用:只需要在返回值的前面加上一个类型参数<T>
* 3、泛型接口:只需要在接口名字的最后加上一个类型参数< T > 就ok啦
* @author Administrator
* @param <T>
* @param <V>
*/
public class Man<T , V> {
//静态变量不能使用泛型
// private static T leg;
private T head;
private T mouth;
private V hand;
public T getHead() {
return head;
}
public void setHead(T head) {
this.head = head;
}
public T getMouth() {
return mouth;
}
public void setMouth(T mouth) {
this.mouth = mouth;
}
public V getHand() {
return hand;
}
public void setHand(V hand) {
this.hand = hand;
}
//泛型方法 的使用
public T getS(List<T> list){
return list.get(0);
}
public static void main(String[] args) {
Man<String ,Integer> m = new Man<String , Integer>();
m.setHand(5);
m.setMouth("Mouth is used to eat !!!");
m.setHead("Head is used to think !!!");
System.out.println(m.getHead()+"\n"+m.getMouth()+"\n Man have five fingers\n"+m.getHand());
//如果在创建对象时没有定义(类型参数)的具体类型,
//使用该类的一些属性是就需要进行强制类型转换了
Man m2 = new Man();
m2.setHand("two Hands");
String st = (String) m2.getHand();
System.out.println(st);
}
}
2、Comparator和Comparable接口的应用实例(利用Collections.sort() Arrays.sort()自动排序时使用)
package xcu.hl.fanxing;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 1、实现comparable接口,重写compareTo()方法来定义对象的比较规则。
* 2、实现Comparator接口,重写compare()方法来定义某个对象比较规则。
* 3、重写两个方法后就可以调用Collections.sort(List<Object>)对相应对象的集合进行排序。
* 4、Arrays.sort(<T extends Number> T []) 就是只能对数组类型的对象进行排序。
* @author java_韩磊
*/
public class Woman implements Comparable<Woman> {
private int age;
private String name;
public Woman(int age, String name) {
this.name = name;
this.age = age;
}
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//定义Woman对象的排序规则
//先按照name排序,如果姓名一样的话就用年龄排序。
@Override
public int compareTo(Woman o) {
if(this.getName().compareTo(o.getName())!=0){
return this.getName().compareTo(o.getName());
}else{
return this.getAge()-o.getAge();
}
}
public static void main(String[] args) {
List<Woman> list= new ArrayList<Woman>();
Woman w = new Woman(12,"abc");
Woman w2 = new Woman(31,"bca");
Woman w3 = new Woman(21,"acb");
Woman w4 = new Woman(51,"bac");
Woman w5 = new Woman(21,"bac");
list.add(w);
list.add(w2);
list.add(w3);
list.add(w4);
list.add(w5);
Double [] d = {1.1,0.2,5.5,3.2,1.0};
//自动调用new WomanComparator()的compare()方法进行排序
//只能对数组对象进行排序,不能对集合对象排序(具体的使用方法看API文档)
Arrays.sort(d,new WomanComparator());
System.out.println("Double类型数据从大到小配需后为:");
for(int i=0;i<d.length; i++){
System.out.print(d[i] +" \t");
}
//自动调用重写的compareTo()方法进行排序,针对集合对象进行排序
Collections.sort(list);
System.out.println();
System.out.println("Woman对象数据按照指定规则为woman排序后为:");
for(Woman woman: list){
System.out.print(woman.getAge()+" " +woman.getName()+" \t");
}
}
}
//继承Comparator接口,重新定义Double类型数据的比较规则。
package xcu.hl.fanxing;
import java.util.Comparator;
public class WomanComparator implements Comparator<Double> {
//重新定义Double类型的排序规则,按照从大到小的规则排序
@Override
public int compare(Double o1, Double o2) {
// TODO Auto-generated method stub
return (int) (o2-o1);
}
}
4. 受限的类型参数和类型通配符“ ? ”
- 将类型参数限制为Number类子类< T extends Number>
- 类型参数 ? , 表示该类型参数可以匹配任何类型。
- ? extends Number 上限通配符
- ? super Number 下限通配符
泛型的难点就是通配符的应用,有兴趣者可以深入研究,这里只是简单介绍泛型的基本用法。