2012-05-17 67 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

相關問題