我的代码在我的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)
我知道这应该意味着我正在改变一个对象,而迭代依赖于它,但我不能为我的生活找出可能发生的地方。任何帮助,将不胜感激。
答案 0 :(得分:2)
您的堆栈跟踪显示代码子列表中的某个位置(直接或间接)传递给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
来源了解有关列表修改检查的更多信息。