Java итераторы и для каждого цикла. любой способ получить доступ к базовому итератору? - PullRequest
7 голосов
/ 15 октября 2010

Мне очень нравится конструкция для каждого цикла (for(T e : iterable)) в Java, которая работает на любом Iterable<T>, потому что во многих случаях очень легко читать и писать код.Интересно, есть ли способ получить доступ к базовому итератору из такого цикла?Это может быть обязательным, если я хочу использовать remove() от итератора.

Ответы [ 6 ]

17 голосов
/ 15 октября 2010

Нет, суть цикла for-each - в том, чтобы абстрагировать основной итератор.

Если вам это нужно, вы должны заявить об этом.

4 голосов
/ 15 октября 2010

Нет, вы не можете удалять объекты в каждом цикле.

Используйте это вместо:

Iterator<Type> it = collection.iterator();

while (it.hasNext()) {
   if (it.next().shouldBeRemoved()) {
       it.remove();
   }
}
1 голос
/ 15 октября 2010

Вы правы, использование Iterator поддерживает возможность безопасного удаления объекта из исходной коллекции, вызывая remove () на самом Iterator. Смысл здесь в том, чтобы избежать исключения ConcurrentModifiedException, которое подразумевает, что коллекция была изменена, когда итератор был открыт для нее. Некоторые коллекции позволят вам убрать или добавить элементы в коллекцию во время итерации по ней, но вызов метода remove () в Iterator является более безопасной практикой.

Но Iterator поддерживает производного и более мощного двоюродного брата ListIterator , доступный только из списков, поддерживает как добавление и удаление из списка во время итерации, так и двунаправленную прокрутку списков.

1 голос
/ 15 октября 2010

Если коллекция достаточно мала, вы можете альтернативно использовать копию коллекции для итерации, если хотите иметь возможность удалять элементы, чтобы вам не пришлось действовать так, как будто у вас две коллекции.

for(T e : collection.clone())
    if(e.shouldBeRemoved())
        collection.remove();

Более того, Apache CollectionUtils (и, вероятно, есть альтернатива Google и универсальная альтернатива) обеспечивает filter(java.util.Collection collection, Predicate predicate).Этот пример возвращает весь список.Вы можете сохранить предикат для повторного использования.

CollectionUtils.filter(collection, new Predicate(){
        boolean evaluate(Object object){return true;}
    });
1 голос
/ 15 октября 2010

Вместо этого используйте цикл for.

0 голосов
/ 15 октября 2010

изменяющие данные имеют неправильное чувство к нему, просто создайте новый Iterable (или коллекцию) и добавьте элементы, которые вы хотите сохранить в нем, остальные времена будут потеряны в цикле for ((вроде**

...