У меня есть для каждого цикла с типом Set.
Пока я просматриваю этот набор, я добавляю к нему элементы.
for (Object o: Set) {
//i do something and add to the set
}
Я продолжаю получать ConcurrentModificationException
. Но я не знаю, как бы я добавил к этому Set
, что не вызвало бы этого исключения. Я не могу создать новый для каждого цикла, который бы не работал.
Может кто-то указать мне верное направление?
Вам нужно либо
Простейшим изменением является
for (Object o: set.toArray()) {
if (condition(o))
set.add(something);
}
С помощью дженериков более простым решением может быть
Set<T> set =
for(T t: new HashSet<T>(set)) {
// something which might add to set
}
Примечание. Это предотвратит повторение итерации элементов, которые вы только что добавили. Примечание2: использование параллельных наборов может привести к появлению добавленных элементов или, возможно, нет.
Если вам действительно нужно видеть элементы при их добавлении, вам нужно использовать список, возможно, вместо этого, а также.
List<T> list = new ArrayList<>(set);
for(int i = 0; i < list.size(); i++) {
T t = list.get(i);
if (condition)
// if it is not a duplicate
if (set.add(something))
list.add(something);
}
Это позволит вам надежно увидеть элементы, добавленные вами в цикл. Примечание: необходимо соблюдать осторожность, чтобы не создавать бесконечный цикл и не хватать памяти.
Альтернативой является использование очереди вместо списка. Это может быть приятнее, но я считаю менее эффективным.
Queue<T> q = new ConcurrentLinkedQueue<>(set);
for(T t : q) {
if (condition)
// if it is not a duplicate
if (set.add(something))
q.add(something);
}
Вы можете сделать временный Set
и добавить свои элементы в этот набор темп, а когда вы закончите перебирать все элементы, добавьте значения из набора темпа в исходный набор
Пример:
Set<Integer> originalSet;
//stuff where you fill your original Set
Set<Integer> tempSet = new Set<Integer>();
for(Integer i : originalSet) {
tempSet.add(<integerToAdd>);
}
originalSet.addAll(tempSet);