北京理工大学计算机系(共 34页) 1
第九讲 范型程序设计北京理工大学计算机系(共 34页) 2
程序设计的风范
结构化
基于对象
面向对象
范型编程北京理工大学计算机系(共 34页) 3
为什么要引入范型?
1 减少类的数目
2 初步剖离数据结构与算法
3 提升程序运行效率
4 减少编码错误:可以在编译时检查类型北京理工大学计算机系(共 34页) 4
先从 Java范型对象容器开始北京理工大学计算机系(共 34页) 5
ArrayList
范型化的动态数组 ArrayList<T>
实例,ArrayListDemo.java
北京理工大学计算机系(共 34页) 6
使用迭代器访问 ArrayList
实例,IteratorDemo.java
迭代器的含义
ArrayList实现了 List接口,而 List接口要求有一个返回 Iterator类型对象的方法。
北京理工大学计算机系(共 34页) 7
另一个容器 LinkedList
范型化的链表
实例,StringStackDemo.java
用 LinkedList实现字串堆栈
实例,StringQueueDemo.java
用 LinkedList实现字串队列北京理工大学计算机系(共 34页) 8
对象集合(一)
集合中的元素不允许重复
Java提供了一个自动哈希排序的集合
HashSet
实例,HashSetDemo.java
北京理工大学计算机系(共 34页) 9
对象集合(二)
按字典次序排序的集合 TreeSet,
实例,TreeSetDemo.java
要自定义排序方法,可以传给 TreeSet一个实现了 Comparator接口的类,由它完成比对对象的工作,CustomComparator.java
运行实例,TreeSetDemo2.java
北京理工大学计算机系(共 34页) 10
键 -对象集合(一)
HashMap类实例,HashMapDemo.java
迭代访问集合中的元素实例,HashMapDemo2.java
LinkedHashMap类,保持元素最初加入的顺序实例,LinkedHashMapDemo.java
北京理工大学计算机系(共 34页) 11
键 -对象集合(一)
TreeMap类
按字典排序:
实例,TreeMapDemo2
自定义排序:
TreeMapDemo2.java
北京理工大学计算机系(共 34页) 12
深入了解范型北京理工大学计算机系(共 34页) 13
自动打包
ArrayList<Integer> list;
list=new ArrayList<Integer>();
list.add(3);
//相当于
//list.add(new Integer(3));
北京理工大学计算机系(共 34页) 14
自动拆包
以下语句:
int n=list.get(0)
将会被自动变换为:
int n=list.get(0).intValue();
北京理工大学计算机系(共 34页) 15
注意
尽量避免在大循环中出现打包与拆包现象。
尽可能明确地定义变量数据类型!
北京理工大学计算机系(共 34页) 16
范型实例:范型数组
ArrayList
实例,ArrayListTest.java
1.创建包容自定义类 Employee对象的范型
ArrayList
2.使用 for each循环北京理工大学计算机系(共 34页) 17
定义自己的范型类
public class Pair<T>
{
public Pair() { first = null; second = null; }
public Pair(T first,T second) { this.first = first; this.second = second; }
public T getFirst() { return first; }
public T getSecond() { return second; }
public void setFirst(T newValue) { first = newValue; }
public void setSecond(T newValue) { second = newValue; }
private T first;
private T second;
}
北京理工大学计算机系(共 34页) 18
范型类应用实例
PairTest1:应用范型类 Pair求字串数组中的最大最小字串北京理工大学计算机系(共 34页) 19
定义范型方法
Class ArrayAlg
{
Public static <T> T getMiddle(T[] a)
{
return a[a.length/2];
}
}
北京理工大学计算机系(共 34页) 20
使用范型方法
String[] ns={“John”,”Q”,”public”};
String mid=ArrayAlg<String>.getMiddle(ns)
北京理工大学计算机系(共 34页) 21
类型变量的限定
public static <T extends Comparable> T
min(T[] a)
{

}
用于指定类型必须实现 Comparable接口。
多个限定条件
T extends Comparable & Serializable
北京理工大学计算机系(共 34页) 22
泛型限定实例
PairTest2.java
北京理工大学计算机系(共 34页) 23
范型类型与“原始”类型
Public class Pair<T>
{
private T first;
private T second;
}
Java会将上述的 T转为 Object,生成一个原始数据类型,以便在 JVM上运行。 ——“擦除”原理
其原因是:
Java虚拟机没有范型类型对象!
北京理工大学计算机系(共 34页) 24
翻译泛型表达式
Pair<Employee> buddies=…;
Employee buddy=buddies.getFirst();
在编译时,编译器将擦除 Pair的范型定义,
以 Object代替 Employee,并在第二句中自动插入强制类型转换。
北京理工大学计算机系(共 34页) 25
翻译范型方法
Public static <T extends Comparable>
T min(T[] a)
擦除之后:
Public static Comparable
Min(Comparable[] a)
必须知道 JVM是如何实现范型的,才能正确地使用范型。
北京理工大学计算机系(共 34页) 26
范型的限制
不适用于基本数据类型,如:
Pair<double>是错的,只能是
Pair<Double>
北京理工大学计算机系(共 34页) 27
范型的限制
Instanceof应用 于范 型时,只处理“擦除”后的原始类型
If (a instanceof Pair<String>)
与 If(a instanceof Pair<T>)结果一样
getClass方法总是返回原始类型
Pair<String> str=…
Pair<Employee> es=..
If(str.getClass()==es.getClass())

上述条件语句总返回 True
北京理工大学计算机系(共 34页) 28
范型的限制
不能抛出也不能捕获范型类的对象
Public class Problem<T> extends
Exception ×
try {…}
catch (T e) {…} ×
北京理工大学计算机系(共 34页) 29
范型的限制
不能定义范型化数组
Pair<String>[] table=new Pair<String>(10);
×
不能直接创建范型类型的实例
public class Pair<T>{
….
public Pair(){
first=new T(); second=new T(); ×
}
….
}
北京理工大学计算机系(共 34页) 30
范型的限制
不要在静态方法和字段中引用类型变量 T。

private static T count; ×
北京理工大学计算机系(共 34页) 31
范型的继承
一个类可以继承自范型类,但要注意以下情况:
S继承自 P,
但 Pair<S>不等于是 Pair<P>的子类!
北京理工大学计算机系(共 34页) 32
范型通配符
Pair<? Extends Employee>
表明它的类型参数是 Employee的子类,如
Pair<Manager>,但不能是 Pair<String>
Pair<? super Employee>
表明它的类型参数是 Employee的父类。
北京理工大学计算机系(共 34页) 33
范型化实例
PairTest3.java
北京理工大学计算机系(共 34页) 34
参考资料
,Java2核心技术卷 I:基础知识,(第 7版)
第 13章,范型程序设计,