【发布时间】:2016-07-14 09:30:26
【问题描述】:
有一个Java函数
public <T> void batchWrite(Iterable<T> source, int number)
以省时的方式写入大量项目。
我想在ConcurrentLinkedQueue 上使用这个batchWrite(),它可以在batchWrite() 工作时写入。我希望batchWrite() 删除它从队列中取出的项目。
我可以编写一个迭代器(并将其包装成一个Iterable)来删除返回的项目:
class IteratorThatRemovesReturnedValues<T> implements Iterator<T> {
Queue<T> queue;
IteratorThatRemovesReturnedValues(Queue<T> q) { queue = q; }
boolean hasNext() { return queue.peek() != null; }
T next() { return queue.poll(); }
}
问题是:这不是滥用这个概念吗?
remove() 的描述说:
如果在迭代过程中底层集合被修改,迭代器的行为是不确定的。
这可以通过任何一种方式读取:Iterator 的特定实现可能被允许或不允许定义当以某种特定方式修改底层免等待队列时会发生什么。
从底层队列中移除返回的元素会与迭代器的约定相矛盾吗?
(替代方法是将poll() 的数量项放入辅助ArrayList 并在该列表上调用batchWrite()。)
编辑这个问题的另一面:迭代器可以由管道支持吗?
【问题讨论】:
-
IMO 你可以用
LinkedList做同样的事情,而不用实现 Iterator 返回已删除的项目... -
是的,它会被滥用。迭代器的 next() 方法不应该被移除。为什么不直接使用队列的迭代器并调用 remove() 呢?
-
我会说完全兼容的迭代器在不调用 remove 时不应该删除元素。想象一下,你为同一个集合创建了两个迭代器,并且想要对它们进行迭代; 繁荣。合同的问题是您可以期待某些行为。如果您的迭代器真的被称为
IteratorThatRemovesReturnedValues,并且您以每个人都知道会发生什么的方式记录它的行为,那么我不会担心官方的预期合同。