是否有效 - 即在联系内,Iterator
返回与先前迭代相同(可变)的对象,或具有共享可变状态的新对象作为先前对象?也就是说,可以调用next()
来使先前调用返回的对象无效,只要它被记录下来了吗?
我完全理解这不是一个好主意一般,而且我没有养成习惯。
但是,在某些情况下,重用相同的底层对象或具有共享内部的新对象(因此可能使先前返回的对象的内部无效)具有重要性和可测量性。一个很好的例子是当迭代器返回的对象以一些偏移和长度指向包含Iterable
的缓冲区数组时,并且在检索后续对象时可能会覆盖此数组。
当然这违反了最不惊讶的原则,并且可能是客户不友好 - 但我很好奇它是否违反Iterator
的联系 - 只要我记录它,我是否遵守规则?< / p>
javadoc似乎是专注于集合,其中next()
调用之间的共享状态可能毫无意义,但Iterator
是一个通用接口(您可以在没有支持集合,甚至没有支持任何)。
基本上我正在尝试在flyweight模式中实现可比性,性能方面的东西,但要保留Java迭代器的细节。
遵循此模式的迭代器可以通过以下方式安全使用:
for (Foo foo : FooIterable) {
if (foo.method()) {
System.println("ha!");
}
}
因为foo
的每个实例都不会从一次迭代转移到另一次迭代。但是,类似下面的内容通常不起作用:
List<Foo> allTheFoos = ...;
for (Foo foo : FooIterable) {
allTheFoos.add(foo);
}
for (Foo foo : allTheFoos) {
...
}
由于第一个循环中的foo
被存储起来,因此逃避了它们的迭代。当您稍后访问它们时,它们的状态可能无效(例如,它们可能看起来都像是从初始迭代返回的最后一个foo
。
答案 0 :(得分:0)
List
可以多次包含同一个对象,并且Iterator
会将此对象返回到列表中出现的位置。因此,这可能不是合同所禁止的。 Set
不应包含重复项,因此不会两次返回相同的对象。
集合永远不会修改或使其成员无效,但是在迭代器本身内部存在类似于您的情况:如果集合已被修改,它将变为无效(并在调用时抛出异常)。这可能是提示要在返回的对象变为无效时执行的解决方案。
也许你的迭代可以更好地返回有关该更改对象的包装器,以确保对先前返回的,现在无效的包装器抛出异常的所有调用。