Я знаю, что такой кодЕсть ли способ выбрать «неуказанное поведение», а не ConcurrentModificationException?
for (Object o: collection){
if (condition(i)){
collection.remove(i);
}
}
бросит ConcurrentModificationException, и я понимаю, почему: изменение коллекции напрямую может повлиять на способность итератора, чтобы отслеживать его место, с помощью, например, оставив его с ссылку на элемент, который больше не является частью коллекции, или заставляя его пропускать тот, который только что был добавлен. Для кода, как выше, это разумное беспокойство, однако, я хотел бы написать что-то вроде
for (Object o: set){// set is an instance of java.util.LinkedHashSet
if (condition(o)){
set.remove(other(o));
}
}
Где другой (о) гарантированно будет «далеко» от о в упорядочении множества. В моей конкретной реализации он никогда не будет меньше 47 шагов «от». Кроме того, если условие (o) истинно, то цикл, о котором идет речь, будет гарантировать короткое замыкание до того, как он достигнет места, где находился другой (o). Таким образом, вся часть набора, к которому обращается итератор, полностью отделена от модифицированной части. Кроме того, особенно сильные стороны LinkedHashSet (быстрая вставка и удаление случайного доступа, гарантированный порядок итераций) кажутся особенно подходящими для этой точной операции.
Я полагаю, что мой вопрос двоякий: во-первых, такая операция все еще опасна с учетом вышеуказанных ограничений? Единственный способ, которым я могу думать, это то, что значения Iterator предварительно загружены заранее и кэшированы, что, я полагаю, улучшит производительность во многих приложениях, но похоже, что это также уменьшит его во многих других, и, следовательно, будет странный выбор для универсального класса от java.util. Но, возможно, я ошибаюсь. Когда дело доходит до таких вещей, как кеширование, моя интуиция об эффективности часто бывает подозрительной. Во-вторых, если предположить, что такая вещь, по крайней мере теоретически, безопасна, есть ли способ, не до конца полностью внедряющий LinkedHashSet или жертвуя эффективностью для достижения этой операции? Могу ли я передать Коллекции, чтобы игнорировать тот факт, что я изменяю другую часть набора, и просто продолжаю свой бизнес, как обычно? Моя текущая работа заключается в том, чтобы сначала добавить элементы в промежуточную коллекцию, а затем добавить их в основной набор после завершения цикла, но это неэффективно, так как он должен дважды добавлять значения.
Если вы хотите неуказанное поведение, ConcurrentModificationException считает это. – user2357112
В любом случае, нет, вы не можете сообщить сборке пропустить параллельные проверки модификации. – user2357112
Справедливо, но я думаю, что мой вопрос достаточно ясен относительно того, что я ищу. Документация для ConcurrentModificationException гласит: «... Итераторы, которые делают это, называются отказоустойчивыми итераторами, поскольку они терпят неудачу быстро и чисто, а скорее рискуют произвольным, недетерминированным поведением в неопределенное время в будущем ...». Я хочу, чтобы это рисковало, потому что в этом конкретном случае такое недетерминированное поведение кажется маловероятным. В качестве альтернативы, если есть достаточно простой и сравнительно эффективный способ переписать код, я так же счастлив сделать это. –