Ada*_*ski 66 java collections iterator
通常认为提供Iterator
"无限"的实现是不好的做法; 即对hasNext()
always(*)的调用返回true的位置?
通常我会说"是",因为调用代码可能表现不正常,但在下面的实现hasNext()
中将返回true,除非调用者从List中删除迭代器初始化的所有元素; 即存在终止条件.你认为这是合法用途Iterator
吗?它似乎没有违反合同,虽然我认为有人可能认为这是不直观的.
public class CyclicIterator<T> implements Iterator<T> {
private final List<T> l;
private Iterator<T> it;
public CyclicIterator<T>(List<T> l) {
this.l = l;
this.it = l.iterator();
}
public boolean hasNext() {
return !l.isEmpty();
}
public T next() {
T ret;
if (!hasNext()) {
throw new NoSuchElementException();
} else if (it.hasNext()) {
ret = it.next();
} else {
it = l.iterator();
ret = it.next();
}
return ret;
}
public void remove() {
it.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
(迂腐)编辑
有些人评论了如何Iterator
使用一个无限序列(如Fibonacci序列)生成值.但是,Java Iterator
文档声明Iterator是:
集合上的迭代器.
现在你可以争辩说Fibonacci序列是一个无限集合但是在Java中我会将集合与java.util.Collection
接口等同起来,它提供了size()
暗示集合必须有界的方法.因此,Iterator
从无界序列中使用作为值的生成器是否合法?
oxb*_*kes 76
我认为这完全合法 - Iterator
只是一堆"东西".为什么流必然是有界的?
许多其他语言(例如Scala)具有内置于其中的无界流的概念,这些可以迭代.例如,使用scalaz
scala> val fibs = (0, 1).iterate[Stream](t2 => t2._2 -> (t2._1 + t2._2)).map(_._1).iterator
fibs: Iterator[Int] = non-empty iterator
scala> fibs.take(10).mkString(", ") //first 10 fibonnacci numbers
res0: String = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
Run Code Online (Sandbox Code Playgroud)
编辑: 就最小惊喜的原则而言,我认为这完全取决于背景.例如,我期望这种方法返回什么?
public Iterator<Integer> fibonacciSequence();
Run Code Online (Sandbox Code Playgroud)
虽然我也认为这是合法的,但我想补充说,这样一个Iterator
(或更确切地说:Iterable
产生这样的一个Iterator
)不会很好地与增强的for循环(也就是每个循环):
for (Object o : myIterable) {
...
}
Run Code Online (Sandbox Code Playgroud)
由于增强型for循环中的代码无法直接访问迭代器,因此无法调用remove()
迭代器.
因此,要结束循环,必须执行以下操作之一:
List
的Iterator
和直接删除的对象,可能挑起ConcurrentModificationException
break
退出循环Exception
退出循环return
离开环路除了最后一个替代方案之外的所有方案都不是保留增强的for循环的最佳方法.
当然,"正常"for循环(或任何其他循环与显式Iterator
变量一起)可以正常工作:
for (Iterator it = getIterator(); it.hasNext();) {
Object o = it.next()
...
}
Run Code Online (Sandbox Code Playgroud)
这可能是语义,但迭代器应该努力返回下一个项目,而不考虑它何时结束.结束是一个集合的副作用,虽然它可能看起来像一个常见的副作用.
那么,无限和10万亿件物品的收藏之间有什么区别?呼叫者要么全部都想要,要么他不想要.让来电者决定要返回多少项或何时结束.
我不会说调用者不能使用for-each构造.他可以,只要他想要所有物品.
集合的文档中的某些内容(如"可能是无限集合")是合适的,但不是"无限迭代器".
归档时间: |
|
查看次数: |
5705 次 |
最近记录: |