迭代
集合类数据类型的基本操作之一就是,能够使用Java的foreach语句通过迭代遍历并处理集合中的每个元素。这种方式的代码既清晰有简洁,且不依赖于集合数据类型的具体实现。如:
Stack<String> collection = new Stack<String>();
......
for(String s : collection){
......
System.out.println(s);
......
}
这里,foreach语句只是while语句的一种简写方式。它的本质和以下while语句是等价的
Iterator<String> i = collection.iterator();
while(i.hasNext()){
......
String s=i.next();
System.out.println(s);
......
}
这段代码展示了一些在任意课迭代的集合数据类型中我们都需要实现的东西:
- 集合数据类型必须实现一个 iterator() 方法并返回一个 Iterator 对象;
- Iterator类必须包含两个方法:hasNext()(返回一个布尔值)和next()(返回集合中一个泛型元素)
在Java中,我们使用接口机制来指定一个类所必须实现的方法。对于可迭代的集合数据类型,Java以及为我们定义了所需的接口。要使一个类可迭代,第一步就是在它的声明中加入
implements Iterable<Item>
对应的接口(即java.lang.Iterable)为:
public interface Iterable<Item>{
Iterator<Item> iterator();
}
然后在类中添加一个方法 iterator() 并返回一个迭代器 Iterator<Item>。迭代器都是泛型的,因此我们可以使用参数类型Item来帮助用例遍历它们指定的任意类型的对象。我们将迭代器命令为 Itr (实际上,这也是ArrayList类中迭代器的命名,大家可以去看看源码),并添加了一下方法:
public Iterator<Item> iterator(){
return new Itr();
}
迭代器是什么,它是一个实现了 hasNext() 和 next() 方法的类的对象,由一下接口定义(即 java.util.Iterator):
public iterface Iterator<Item>{
boolean hasNext();
Item next();
void remove();
}
尽管接口指定了一个 remove() 方法,但是我们希望避免在迭代中穿插能够修改数据结构的操作,因此此方法我们置空。它们实现在集合类的一个嵌套类中:
/*使用嵌套类的方式实现迭代器接口,并实现迭代主要功能*/
private class Itr implements Iterator<Item> {
private int i=N;
@Override
public boolean hasNext() {
return i>0;
}
@Override
public Item next() {
return a[--i];
}
/*我们希望避免在迭代中穿插能够修改数据结构的操作,因此此方法我们置空*/
@Override
public void remove(){}
}
程序示例
集合类:一种定容泛型类型栈(FixedCapacityStack)
package com.li.iterator;
import java.util.Iterator;
/*实现迭代功能接口,并使用泛型机制*/
/*一种定容泛型类型栈*/
public class FixedCapacityStack<Item> implements Iterable<Item>{
private Item[] a; //stack entries
private int N; //size, basic data types, N default value 0
@SuppressWarnings("unchecked")
public FixedCapacityStack(int cap) {
a=(Item[]) new Object[cap];
}
public boolean isEmpty() {
return N==0;
}
public int size() {
return N;
}
public void push(Item item) {
a[N++]=item;
}
public Item pop() {
return a[--N];
}
/*返回迭代器的方法*/
@Override
public Iterator<Item> iterator() {
return new Itr();
}
/*使用嵌套类的方式实现迭代器接口,并实现迭代主要功能*/
private class Itr implements Iterator<Item> {
private int i=N;
@Override
public boolean hasNext() {
return i>0;
}
@Override
public Item next() {
return a[--i];
}
/*我们希望避免在迭代中穿插能够修改数据结构的操作,因此此方法我们置空*/
@Override
public void remove(){}
}
}
测试
package com.li.iterator;
import java.util.Iterator;
public class IteratorTest {
public static void main(String[] args) {
FixedCapacityStack<String> f=new FixedCapacityStack<String>(50);
f.push(new String("01"));
f.push(new String("02"));
f.push(new String("03"));
f.push(new String("04"));
f.push(new String("05"));
Iterator<String> i=f.iterator();
/*两种等价的迭代方式*/
while(i.hasNext()) {
System.out.println(i.next());
}
System.out.println("----Delimiter----");
for(String s : f) {
System.out.println(s);
}
}
}
运行结果
05
04
03
02
01
----Delimiter----
05
04
03
02
01