【问题标题】:Is there an Iterable which allows Iterable.remove() to be called by another instance?是否有一个 Iterable 允许 Iterable.remove() 被另一个实例调用?
【发布时间】:2012-05-17 10:58:37
【问题描述】:

是否有用于 List 对象的 Guava 迭代器(或方法),它允许两个迭代器实例存在 - 在同一内存范围内 - 同时允许 remove() 操作? (奖励点:如果它适用于集合)。

示例用例:通过集合的外部和内部迭代,其中内部循环可能决定删除一个元素,而外部循环随后会跳过它。

想象一下,通过减少循环中要比较的元素数量并消除在最后从列表中删除空集的需要,它将如何使以下概念代码(使用 Guava 静态导入)受益:

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

【问题讨论】:

    标签: java collections guava


    【解决方案1】:

    标准库中似乎不存在这样的实现。

    【讨论】:

      【解决方案2】:

      为什么不用 NO_EMPTIES 过滤外观?由于过滤器在迭代期间被评估,任何新的空集都不会在过滤列表/外循环中返回。

      否则,我不这么认为。你会在外循环上得到一个ConcurrentModificationException

      【讨论】:

      • 那会导致算法失效,我会把测试用例留给读者;-)
      • 怎么样?因为最后会过滤掉空集。
      • 内循环创建空集,外循环可能永远无法再次到达。这有点离题了 ;-) 问题是关于 Iterables,而不是其他编写示例用例的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多