我有在Main方法中进入for循环的代码。
for (List<Point2D> points : output) {
currentPath = pathDistance(points);
if (shortest == 0){
shortest = currentPath;
} else if (currentPath < shortest) {
best = points;
shortest = currentPath;
}
}
其中
pathDistance
定义为public static Double pathDistance(List<Point2D> path){
double distance = 0;
int count = path.size()-1;
for (int i = 0; i < count; i++) {
distance = distance + path.get(i).distance(path.get(i+1));
}
distance = distance + path.get(0).distance(path.get(count));
return distance;
}
但我不断得到错误
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(Unknown Source)
at java.util.SubList.size(Unknown Source)
at java.util.Collections$SynchronizedCollection.size(Unknown Source)
at TSMain.pathDistance(TSMain.java:76)
at TSMain.main(TSMain.java:203)
我知道这应该意味着我正在更改对象,而迭代取决于该对象,但是我无法终生弄清楚可能会发生在哪里。任何帮助,将不胜感激。
最佳答案
您的堆栈跟踪显示代码subList中的某处(直接或间接)传递给 Collections.synchronizedCollection
。像这样
Set<List<Point2D>> output = Collections.singleton(
Collections.synchronizedCollection(data.subList(start, end)));
但是,它不会复制
data
列表。并且points
subList仍指向data
列表中的范围。并且原始列表在momet path.size()
调用发生时被修改。您可以通过在将其传递给
pathDistance
之前进行显式列表复制来轻松解决问题for(List<Point2D> points : output){
List<Point2D> pointsCopy = new ArrayList<>(points)
currentPath = pathDistance(pointsCopy);
// rest of code using pointsCopy
}
我还应该注意,您的代码中似乎存在同步问题。在同步集合中包装子列表是一个坏主意,因为原始列表可能会以不安全的方式修改而没有适当的同步。
您可以通过查看
AbstractList#modCount
源来了解有关列表修改检查的更多信息。