如果你所做的只是一次简单的一次迭代(即只有hasNext()
和next()
,没有remove()
),你能保证线性时间表现和/或摊销吗?每次操作的成本是否恒定?
这是在Iterator
合同中指定的吗?
是否存在无法在线性时间内迭代的数据结构/ Java Collection
?
java.util.Scanner implements Iterator<String>
。 Scanner
几乎不是数据结构(例如remove()
完全没有意义)。这被认为是设计上的错误吗?
像PrimeGenerator implements Iterator<Integer>
这样的设计被认为是不好的设计,或者这正是Iterator
的用途? (hasNext()
始终返回true,next()
根据需要计算下一个数字,remove()
没有意义。)
同样,它对java.util.Random implements Iterator<Double>
是否有意义?
如果某个类型实际上只使用了其三分之一的API,那么该类型是否真正实现了Iterator
? (即没有remove()
,总是hasNext()
)
答案 0 :(得分:7)
没有这样的保证。正如你所指出的,任何人都可以将任何东西建模为Iterator。迭代器的各个生产者必须指定他们的个人表现。
答案 1 :(得分:3)
Iterator
documentaton中没有任何内容提及任何性能保证,因此无法保证。
在这种通用工具上要求这种约束也没有意义。
一个更有用的约束是文档iterator()
方法,用于指定此Iterator
实例实现的时间约束(例如Iterator
上的Collection
通用hasNext()
很可能能够保证线性时间操作。)
同样,文档中的任何内容都不需要false
返回Iterator
,因此无限Iterator
将完全有效。
但是,通常假设所有Iterator
实例的行为类似于Collection.iterator()
返回的{normal} {{1}}实例,因为它们会返回一定数量的值并且结束在某些时候。文档并不要求这样做,严格来说,任何依赖于该事实的代码都会被巧妙地破坏。
答案 2 :(得分:1)
对于Iterator
,您的所有提案都合理。 API文档明确表示不需要支持remove
,并建议不要使用与Enumeration
类似的旧版Iterator
,除非不删除。
此外,无限长度流是函数式编程中非常有用的概念,可以使用始终为Iterator
的{{1}}来实现。它可以处理任何一种情况。
答案 3 :(得分:1)
听起来你正在考虑列表或集遍历意义上的迭代器。我认为一个更有用的心理模型是一个离散的对象流,你想要一次一个地处理,可以根据离散实例从源流式传输。
从这个意义上说,素数或列表对象的流都是有意义的,而且模型并不暗示数据源的有限性。
答案 4 :(得分:0)
我可以想象一下这个用例..它看起来很直观。就个人而言,我认为没关系。
for(long prime : new PrimeGenerator()){
//do stuff
if(condition){
break;
}
}