Я пытаюсь добавить элемент в ArrayList в определенном порядке
Iterator<Rating> it = arr.iterator();
while(it.hasNext()){
Rating o = it.next();
int index = arr.indexOf(o);
if (o.getRating() < this.getRating()) {
arr.add(index, this);
}
}
Я получаю ConcurrentModificationException при попытке сделать это. Есть ли какое-то простое решение для решения этой проблемы?
Возможно, вместо ArrayList
подойдет одна из следующих коллекций?
КопиОнВритеАррайлист позволит вам писать, не вызывая ConcurrentModificationException
. Является ли это хорошим выбором или нет, зависит от относительной частоты операций записи в итерациях.
Кроме того, обратите внимание на PriorityQueue, поскольку он будет автоматически обрабатывать порядок, или ПриоритетБлокингОчередь, если есть соображения одновременного использования.
Но даже параллельные структуры данных не должны изменяться из того же итератора, пока вы выполняете итерацию по ним. Результат может быть не таким, как вы ожидаете.
@knittl Вы имели в виду должен быть изменен из того же итератора? ConcurrentModificationException возникает, если коллекция изменяется вне итератора. Если модифицировать через итератор, то работает нормально.
@MarkRotteveel извините, я не ясно выразился. Вы не должны изменять коллекцию с помощью методов коллекции. Вызов методов на итераторе в порядке (как вы указали, спасибо!). Изменение их из другого потока допустимо для параллельных коллекций. Чего не следует делать, так это (упрощенно): var iterator = coll.iterator(); while (iterator.hasNext()) { coll.remove(iterator.next()); }
(или добавлять, устанавливать и т.д.) Вы не получите исключения, но оно почти наверняка намекает на недочет в вашей программе или на непонимание того, как работают коллекции (помимо очевидного O (n²) поведение в моем примере).
Если вы можете получить
listIterator()
, вызвав add на итераторе. В противном случае: найти индекс, добавить элемент после итерации