Java 迭代

许多时候,代码要用某种方式处理集合中的每个元素,或者叫做迭代访问集合中的所有元素。比如我们迭代访问数组中的所有元素,将其依次打印出来。

为迭代数组,我们可以用 for(int i = 0; i < a.length; i++) {} 也可以用 foreach 语句 for(int i : a) {}

能不能让我们自己定义的数据类型也支持 foreach 迭代?

比如现在有一个自定义栈 ResizingArrayStack。如何让它支持以下操作?

ResizingArrayStack<String> collection = new ResizingArrayStack<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);
}

所以,要支持 foreach 迭代:

❏ 首先,ResizingArrayStack 必须实现一个 iterator() 方法,该方法返回一个 Iterator 对象;

❏ 其次,其支持的 iterator() 方法返回的 Iterator 对象必须支持两个方法:hasNext()(返回一个布尔值,用来判断是否还有下一个迭代元素)和 next()(返回 ResizingArrayStack 中的下一个迭代元素)。

Java 使用接口机制来指定一个类所必须实现的方法,要使 ResizingArrayStack 类可迭代,第一步就是让它实现 Iterable 接口,要实现 Iterable,先要在 ResizingArrayStack 类声明中加入 implements Iterable<Item>

public class ResizingArrayStack<Item> implements Iterable<Item>
{
	...
}

然后在类中添加一个 iterator() 方法用来返回一个迭代器 Iterator<Item>,不同的可迭代类型应该有不同的迭代器,这里将 ResizingArrayStack 的迭代器命名为 ResizingArrayStackIterator。

public Iterator<Item> iterator()
{  return new ResizingArrayStackIterator();  }

迭代器是一个实现了 hasNext() 和 next() 方法的类的对象,类似地,通过实现 Iterator 接口来约定 ResizingArrayStackIterator 类必须实现这两个方法,同时我们根据数据类型的迭代要求写好 hasNext() 和 next() 中的迭代逻辑(这里省略):

private class ResizingArrayStackIterator implements Iterator<Item>
{
	...
	public boolean hasNext() { ... }
	public    Item next()    { ... }
}

最后,Iterator 接口不在 java.lang 中,需要用 import java.util.Iterator; 将其导入。

所以一个可迭代的 ResizingArrayStackIterator 类应该是这样:

import java.util.Iterator;
public class ResizingArrayStack<Item> implements Iterable<Item>
{
	...
	public Iterator<Item> iterator()
	{ return new ResizingArrayStackIterator(); }
	private class ResizingArrayStackIterator implements Iterator<Item>
	{
		...
		public boolean hasNext() { ... }
		public    Item next()    { ... }
	}
}

另,Iterator 接口中还有一个 remove() 方法,只需要用 foreach 来访问数据时可不实现。

总结自《算法(第四版)》1.3 背包、队列和栈

posted @ 2022-01-29 17:06  Higurashi-kagome  阅读(354)  评论(0编辑  收藏  举报