Я пытаюсь понять, есть ли возможность для чего-то (не говорите мне, что это не так, это мой неудачный проект) по расположению точек и их расстояний.
for (Point p1 : results) {
remove.clear();
for (Point p2 : results) {
if (Math.sqrt(
Math.pow(p1.getX() - p2.getX(), 2)
+ Math.pow(p1.getY() - p2.getY(), 2)
) % 1 > 0) {
results.remove(p2);
}
}
}
По сути, я пытаюсь проверить, имеют ли две точки целочисленное расстояние, и, если нет, удалить его из набора и сделать это для всех точек (которые остались).
Однако я получаю ConcurrentModificationException
и не знаю, как его реорганизовать для выполнения той же задачи, не вызывая ошибки другим способом.
Есть ли способы обойти это или это просто ограничение Java?
РЕДАКТИРОВАТЬ: хотя дублирующая предложенная ссылка предлагает понимание, сосредоточение ответов на одиночных петлях имеет место излишка, что не применимо. Если этот вопрос повторяется, это означает, что использование Iterator - это только ответ.
4 ответа
Некоторые реализации Collection
используют итератор « безотказно ». При удалении элемента из Collection
напрямую (с использованием Collection#remove
) во время итерации по нему будет возникать исключение.
Расширенные циклы for используют итератор коллекции для итерации по коллекции.
Вы можете изменить свои расширенные циклы на обычные циклы for:
for(int i = 0; i < results.size(); i++) {
for(int j = 0; j < results.size(); j++) {
Point result = results.get(j);
if(...) {
//results.remove(j); or
//results.remove(result);
}
}
}
Как упоминалось в комментариях, это не сработает для Set
. В этом случае вы можете просто сохранить ссылку на итератор коллекции и использовать ее для удаления элемента:
Iterator<Point> firstIter = results.iterator();
while(firstIter.hasNext()) {
Point p1 = iterator.next();
Iterator<Point> secondIter = results.iterator();
while(secondIter.hasNext()) {
Point p2 = secondIter.next();
if(...) {
secondIter.remove();
}
}
}
results
является List
, но не Set
или другим типом Collection
.
Вы могли сделать это:
Iterator<Point> iterator = results.iterator();
while (iterator.hasNext()) {
Point p1 = iterator.next();
boolean shouldBeRemoved = false;
for(Point p2 : results) {
if (p2 != p1 && (Math.sqrt(Math.pow(p1.getX() - p2.getX(), 2)
+ Math.pow(p1.getY() - p2.getY(), 2))
% 1 > 0)) {
shouldBeRemoved = true;
break;
}
}
if (shouldBeRemoved) {
iterator.remove();
}
}
Разница в том, что, очевидно, удаляется p1
вместо p2
, но поскольку мы имеем дело с Set
здесь ...
удалить его из набора
... порядок не важен, правда?
ConcurrentModificationException
. Действительно ли опубликованный мной код вызывает такое исключение?
Set
неупорядочены. И набор не пишется с заглавной буквы.
Похоже, это происходит из-за того, что вы пытаетесь удалить ту же структуру Point. Рассмотрим случай с первым пунктом. И p1, и p2 относятся к первой точке результатов. Расстояние между p1 и p2 равно нулю, потому что они относятся к одной и той же точке. Затем вы пытаетесь удалить p2, который на самом деле является p1. См. Ссылку http://docs.oracle. com / javase / 7 / docs / api / java / util / ConcurrentModificationException.html, чтобы узнать больше о том, почему вы можете получить это исключение даже в случае, когда один поток пытается получить доступ и изменить некоторую структуру.
Вы можете изменить приведенный выше код следующим образом: -
boolean[] if_deleted = new boolean[results.size()];
for (int i = 0; i < results.size(); ++i) {
if_deleted[i] = false;
}
for (int i = 0; i < results.size(); ++i){
for(int j = i + 1; j < results.size(); ++j)
Point p1 = (Point)results.get(i);
Point p2 = (Point)results.get(j);
if (!if_deleted[i] && !if_deleted[j]) {
if (Math.sqrt(
Math.pow(p1.getX() - p2.getX(), 2)
+
Math.pow(p1.getY() - p2.getY(), 2))
% 1 > 0){
if_deleted[j] = true;
results.remove(p2);
}
}
}
}
for (int i = 0; i < results.size(); ++i) {
if (if_deleted[i]) {
results.remove(i);
}
}
results
является List
, но не Set
или другим типом Collection
.
Я рефакторинг
for (int p1 = 0; p1 < results.size() ; p1++){
for (int p2 = p1; p2 < results.size() ; p2++){
if (Math.sqrt(
Math.pow(results.get(p1).getX() - results.get(p2).getX(), 2)
+
Math.pow(results.get(p1).getY() - results.get(p2).getY(), 2))
% 1 > 0){
results.remove(p2);
p2--;
}
}
}
Но я не уверен, что он работает так, как я ожидал.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.