2012-05-17 3 views
2

Существует ли Иватор Гуавы (или методология) для объектов списка, который позволяет двум экземплярам итератора существовать - в той же области памяти - при разрешении операции 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

Смежные вопросы