Скажем, у меня есть объект List и итератор для этого списка.
Сейчас сортирую список с java.util.Collections.sort()
Я знаю, что эту проблему можно обойти, изменив дизайн программы, например, клонируя список, но я конкретно хочу знать «официальное» поведение Java.




Итераторы обычно недействительны после модификации Любые их базовых коллекций, за исключением самого итератора. (Например, ListIterator позволяет вставлять и удалять.)
Я бы определенно ожидал, что любые итераторы станут недействительными после сортировки - а если бы это было не так, я бы не знал, какой порядок ожидать.
@uvsmtid: кроме этого конкретного итератора. Если у вас есть два итератора для одной и той же коллекции, вы не можете изменить коллекцию через любой из них, если только это не коллекция, которая явно поддерживает одновременное изменение.
Как правило, любые изменения в коллекции делают ее итераторы недействительными. Мутация, выполненная с помощью итератора, не сделает этот итератор недействительным. Есть несколько исключительных реализаций коллекций, например CopyOnWriteArrayList.
Общее решение - отсортировать копию коллекции или воссоздать итераторы.
Большинство коллекций в java.util работают без сбоев, и май генерирует ConcurrentModificationException, если базовая коллекция изменяется. Следует отметить, что это предназначено для отладки и поэтому не гарантируется. Согласно javadocs, это верно для всех потомков AbstractList, но это нет верно для CopyOnWriteArrayList, который предназначен для многопоточного использования.
Я написал код, чтобы увидеть, что происходит, когда коллекция сортируется во время итерации. Кажется, что итератор не генерирует никаких исключений, но продолжает нормально выполнять итерацию. Тем не менее, это дает неправильные результаты, если вы ожидаете перебирать несортированную коллекцию. Посмотри на это :
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("D");
list.add("B");
list.add("A");
list.add("C");
list.add("E");
Iterator<String> it = list.iterator();
String s = it.next();
System.out.println(s);
s = it.next();
System.out.println(s);
Collections.sort(list);
Iterator<String> it2 = list.iterator();
s = it.next();
System.out.println(s);
s = it.next();
System.out.println(s);
s = it.next();
System.out.println(s);
while (it2.hasNext()) {
System.out.println(it2.next());
}
}
Надеюсь, это поможет.
Где "обычно" включает "может снова увидеть тот же элемент" ... Честно говоря, я немного разочарован тем, что это не вызывает исключения.
Исключение не гарантируется, оно предназначено для отладки.
Это ясный ответ для единственного итератора
p, указывающего на коллекциюc. Как насчет того, чтобы два итератораpиqуказывали на одну и ту же коллекциюcи повторялись независимо? Означает ли "кроме самого итератора" конкретный экземпляр итератора, напримерp, или любой экземпляр итератора? Я предполагаю, что независимая итерацияpиqаннулирует друг друга (просто потому, что ни итераторы не знают о других итераторах, ни коллекция не запоминает все свои итераторы), но здесь полезно уточнить это. Спасибо!