2

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

2 回答 2

0

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

于 2012-07-12T16:56:11.330 回答
-1

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

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

于 2012-05-17T11:09:07.793 回答