是否有List对象的Guava Iterator(或方法)允许两个迭代器实例存在 - 在相同的内存范围内 - 同时允许remove()操作? (奖励点:如果它适用于收藏)。是否有Iterable允许Iterable.remove()被另一个实例调用?
示例用例:通过集合进行外部迭代和内部迭代,其中内部循环可能决定删除元素,外部循环会随后跳过它。
想象一下它是如何造福于以下概念代码通过减少元件的数量在循环比较,也不再需要在年底从列表中删除空组(使用番石榴静态进口):
private <T> Set<Set<T>> disjointify(Collection<Set<T>> sets) {
List<Set<T>> disjoint = newArrayList(sets);
for (Set<T> set1 : disjoint) {
for (Set<T> set2 : filter(disjoint, not(equalTo(set1)))) {
if (!intersection(set1, set2).isEmpty()) {
// this wouldn't be safe for a Set<Set<T>>
set1.addAll(set2);
set2.clear();
}
}
}
return newHashSet(filter(disjoint, NO_EMPTIES));
}
private static final Predicate<Set<?>> NO_EMPTIES = new Predicate<Set<?>>() {
@Override
public boolean apply(Set<?> input) {
if (input == null || input.isEmpty()) {
return false;
}
return true;
}
};
注意:人们可以很容易想象创建实现 - 特别是对于LinkedList - 我只是问是否已经存在。为了记录,如果一个有效的Iterable已经存在,并为Sets工作,那么用例如下所示(我创建了自己非常低效的Iterable,它实现了这一点,但它的长度为50行,因此我使用上面的原始代码):
private <T> void disjointify(Set<Set<T>> sets) {
for (Set<T> set1 : nestable(sets)) {
Iterator<Set<T>> it = filter(nestable(sets), not(equalTo(set1))).iterator();
while (it.hasNext()) {
Set<T> set2 = it.next();
if (!intersection(set1, set2).isEmpty()) {
set1.addAll(set2);
it.remove();
}
}
}
}
这会导致破坏的算法,我会离开测试案例的读者;-) – fommil
如何呢?由于空集在结尾被过滤掉。 –
内部循环创建空集,外部循环可能永远不会再次到达这些空集。这有点偏离主题;-)问题是关于Iterables,而不是其他写例子用例的方式。 – fommil