为什么?最佳方法是将迭代器项指针移动到第一个位置吗?
为什么要这样做?
因为如果你强制迭代器拥有一个重置(reset)方法,那么每个迭代器都必须拥有一个重置方法。这会给每个迭代器的编写者增加额外的工作量。此外,有些迭代器非常难(或非常昂贵)重置,而你不希望用户对它们调用重置方法。文件或流迭代器是很好的例子。
将迭代器指针移动到第一个位置的最佳方法是什么?
创建一个新的迭代器。这通常比重置操作更少开销。
一旦你读取了一个流,如果不重新打开源文件,就无法重新读取它。这就是流和迭代器的工作原理。
在JCF中采用了一种普遍的趋势 - 保持接口极简,除非这使得某些特性的使用变得极其困难。 这就是为什么您没有针对像不可变集合、固定大小集合等语义的单独接口的原因。
至于为什么提供了remove(Object)
(作为可选项)- 不提供此功能将使在迭代集合时安全地删除项目变得不可能 - 没有任何东西使提供reset()
如此必要。
同样地,为什么还有一个单独的ListIterator()
(提供像previous()
和previousIndex()
之类的方法) - 对于List
接口,在使用时主要的功能是能够根据索引布局元素,并且能够按索引顺序访问它们,无论是固定顺序还是随机顺序。 这在其他集合中并不适用。如果不为List
提供此接口,将使使用列表变得非常困难,甚至不可能。
Iteratable
和Iterator
都可以执行一些有用的操作,这些操作本应该包含在接口中,但实际上并没有。有用的迭代器方法包括skip
[相当于N个连续的移动调用,尽管许多迭代器可以在O(1)时间内实现它]和copyLocation
[它将返回一个预期产生与原始迭代器相同项的迭代器]。任何迭代器都可以实现skip
方法,而任何非巨大有限迭代器都可以通过枚举自身到数组中来实现copyLocation
,然后同时具有它和副本... - supercat提示:将您的迭代变量作为函数创建,然后可以多次使用它。这仅适用于基础逻辑可重复的情况。
在Scala中的示例(Java类似但我没有一个Java REPL手头)
def i = (1 to 100) iterator // i is our iterator
i.grouped(50) foreach println // prints two groups
i.grouped(50) foreach println // prints same two groups again