2012-05-17 33 views
2

是否有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(); 
      } 
     } 
    } 
} 

回答

0

看起来这样的实现在标准库中不存在。

-1

为什么不仅仅用NO_EMPTIES过滤外观呢?由于在迭代过程中评估过滤器,因此任何新的空集都不会在已过滤的列表/外部循环中返回。

否则,我不这么认为。您将在外部循环上获得ConcurrentModificationException

+1

这会导致破坏的算法,我会离开测试案例的读者;-) – fommil

+0

如何呢?由于空集在结尾被过滤掉。 –

+0

内部循环创建空集,外部循环可能永远不会再次到达这些空集。这有点偏离主题;-)问题是关于Iterables,而不是其他写例子用例的方式。 – fommil

相关问题