遍历是collection一项常用的最基本功能。Java有很多种遍历,这里我只总结foreach遍历。
foreach遍历使用起来非常简单,而且不需要过多暴露collection内部细节。
比如Stack:
Stack<String> collection = new Stack<>();
...
for(String s : collection)
System.out.println(s);
...
其实,以上代码是下面代码的简化版:
Iterator<String> i = collection.iterator();
while(i.hasNext())
{
String s = i.next();
System.out.println(s);
}
事实上,为了实现foreach遍历,我们首先应该先让集合类实现Iterable接口,即先声明该集合类是可以遍历的 。
然后,Iterable接口只规定了一个需要返回Iterator类型的方法,所以接下来我们需要重写该方法。
再然后,这个Iterator类型是什么?它实际上是一个实现了Iterator接口的类。而Iterator接口要求实现hasNext(),next(),remove()方法。实际上,remove()方法不要求必须实现,我们一般也不会实现这个方法,因为我们不希望在遍历的同时改变数据结构。
以上涉及Iterable接口,Iterator接口,以及Iterator类型。前两者是接口,最后一个是类。
回到前面Stack的例子,Stack之所以具有foreach遍历功能,是因为Java早已为我们实现了Iterable接口,并建立了一个实现了Iterator接口的类,然后重写Iterator方法返回该类(Iterator类型)。
下面是我自己定义的一个类,它实现了foreach功能。
//由于历史原因,Iterator接口不在Java.lang包里面,而是在Java.util里面,
//因此使用时必须提前导入。
import java.util.Iterator;
public class MyList<Item> implements Iterable<Item>
{
private int N = 0;
private Node first;
private class Node
{
Item item;
Node next;
}
private void addElement(Item item)
{
if(first == null){
first = new Node();
first.item = item;
}else{
Node oldFirst = first;
first = new Node();
first.item = item;
first.next = oldFirst;
}
N++;
}
//重写Iterable要求的方法,即返回一个实现了Iterator接口的类。
public Iterator<Item> iterator()
{
return new MyIterator();
}
//设计一个实现了Iterator接口的类,提供给Iterable要求的方法,以让其返回。
private class MyIterator implements Iterator<Item>
{
Node begin = first;
public boolean hasNext()
{
return begin != null;
}
public Item next()
{
Item item = begin.item;
begin = begin.next;
return item;
}
}
public static void main(String[] args)
{
MyList<String> ml = new MyList<String>();
ml.addElement("item1");
ml.addElement("item2");
ml.addElement("item3");
ml.addElement("item4");
ml.addElement("item5");
ml.addElement("item6");
ml.addElement("item7");
//Iterator类型,实际上是一个实现了Iterator接口的类。
Iterator iterator = ml.iterator();
//foreach遍历。
while(iterator.hasNext())
{
System.out.println(iterator.next());
}
//或者:
for(String s : ml)
{
System.out.println(s);
}
}
}
运行结果如下:
item7
item6
item5
item4
item3
item2
item1
我写的这个类实现了Stack的部分功能。