8.3 迭代器
8.3 迭代器
在任何集合类中,必须通过某种方法在其中置入对象,再用另一种方法从中取得对象。毕竟,容纳各种各样的对象正是集合的首要任务。在
若从更高的角度看这个问题,就会发现它的一个缺陷:需要事先知道集合的准确类型,否则无法使用。乍看来,这一点似乎没什么关系。但假若最开始决定使用
可利用“迭代器”(Iterator)的概念达到这个目的。它可以是一个对象,作用是遍历一系列对象,并选择那个序列中的每个对象,同时不让客户程序员知道或关注那个序列的基础结构。此外,我们通常认为迭代器是一种“轻量级”对象;也就是说,创建它只需付出极少的代价。但也正是由于这个原因,我们常发现迭代器存在一些似乎很奇怪的限制。例如,有些迭代器只能朝一个方向移动。
②
只可用
//: CatsAndDogs2.java
// Simple collection with Enumeration
import java.util.*;
class Cat2 {
private int catNumber;
Cat2(int i) {
catNumber = i;
}
void print() {
System.out.println("Cat number " +catNumber);
}
}
class Dog2 {
private int dogNumber;
Dog2(int i) {
dogNumber = i;
}
void print() {
System.out.println("Dog number " +dogNumber);
}
}
public class CatsAndDogs2 {
public static void main(String[] args) {
Vector cats = new Vector();
for(int i = 0; i < 7; i++)
cats.addElement(new Cat2(i));
// Not a problem to add a dog to cats:
cats.addElement(new Dog2(7));
Enumeration e = cats.elements();
while(e.hasMoreElements())
((Cat2)e.nextElement()).print();
// Dog is detected only at run-time
}
} ///:~
我们看到唯一的改变就是最后几行。不再是:
for(int i = 0; i < cats.size(); i++)
((Cat)cats.elementAt(i)).print();
而是用一个
while(e.hasMoreElements())
((Cat2)e.nextElement()).print();
使用
//: HamsterMaze.java
// Using an Enumeration
import java.util.*;
class Hamster {
private int hamsterNumber;
Hamster(int i) {
hamsterNumber = i;
}
public String toString() {
return "This is Hamster #" + hamsterNumber;
}
}
class Printer {
static void printAll(Enumeration e) {
while(e.hasMoreElements())
System.out.println(
e.nextElement().toString());
}
}
public class HamsterMaze {
public static void main(String[] args) {
Vector v = new Vector();
for(int i = 0; i < 3; i++)
v.addElement(new Hamster(i));
Printer.printAll(v.elements());
}
} ///:~
仔细研究一下打印方法:
static void printAll(Enumeration e) {
while(e.hasMoreElements())
System.out.println(
e.nextElement().toString());
}
注意其中没有与序列类型有关的信息。我们拥有的全部东西便是
这个看似特殊的例子甚至可以更为通用,因为它使用了常规的
System.out.println("" + e.nextElement());
它采用了封装到
System.out.println((String)e.nextElement())
但我们想做的事情通常并不仅仅是调用