gpt4 book ai didi

java - 更新值时出现 ConcurrentModificationException

转载 作者:行者123 更新时间:2023-12-01 17:52:21 25 4
gpt4 key购买 nike

update 函数应通过调用函数 test 来更新 HashMap 中的每个值以确定新值。 test 函数返回 1 或 0,具体取决于其周围的 8 个位置/邻居。尽管如此,每次程序到达更新函数时我都会收到 ConcurrentModificationException 。

private static void update(){
for(Cell e : map.keySet()){
map.put(e,test(e.getX(),e.getY()));
}
}

private static int test(int i, int j){
//count alive neighbors
int sum = 0;
if(map.get(new Cell(i-1, j - 1)) == null){
map.put(new Cell(i-1, j - 1), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i-1, j - 1));
} else {
sum += map.get(new Cell(i-1, j - 1));
}

if(map.get(new Cell(i, j - 1)) == null){
map.put(new Cell(i, j - 1), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i, j - 1));
} else {
sum += map.get(new Cell(i, j - 1));
}

if(map.get(new Cell(i + 1, j - 1)) == null){
map.put(new Cell(i + 1, j - 1), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i + 1, j - 1));
} else {
sum += map.get(new Cell(i + 1, j - 1));
}

if(map.get(new Cell(i + 1, j)) == null){
map.put(new Cell(i + 1, j), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i + 1, j));
} else {
sum += map.get(new Cell(i + 1, j));
}

if(map.get(new Cell(i + 1, j + 1)) == null){
map.put(new Cell(i + 1, j + 1), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i + 1, j + 1));
} else {
sum += map.get(new Cell(i + 1, j + 1));
}

if(map.get(new Cell(i, j + 1)) == null){
map.put(new Cell(i, j + 1), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i, j + 1));
} else {
sum += map.get(new Cell(i, j + 1));
}

if(map.get(new Cell(i - 1, j + 1)) == null){
map.put(new Cell(i - 1, j + 1), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i - 1, j + 1));
} else {
sum += map.get(new Cell(i - 1, j + 1));
}

if(map.get(new Cell(i - 1, j)) == null){
map.put(new Cell(i - 1, j), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i - 1, j));
} else {
sum += map.get(new Cell(i - 1, j));
}

//return to be alive or dead
int temp = 0;
if(map.get(new Cell(i,j)) == 1){
if(sum < 2){
temp = 0;
} else if(sum == 2 || sum == 3){
temp = 1;
} else if(sum > 3){
temp = 0;
}
} else {
if(sum == 3){
temp = 1;
}
}
return temp;
}

最佳答案

我不想回答您的问题(已经完成),而是想帮助您改进编码。

因为您正在使用 map.get(new Cell(i-1, j-1)),所以我希望您已提供 Cell#hashcode() 的实现Cell#equals()。如果没有,请阅读 HashMap 的工作原理,然后立即实现这些方法。

考虑以下代码:

if (map.get(new Cell(i-1, j-1)) == null){
map.put(new Cell(i-1, j-1), ((Math.random()<0.5)?0:1));
sum += map.get(new Cell(i-1, j-1));
}
else{
sum += map.get(new Cell(i-1, j-1));
}

在这里,您调用了new Cell(i-1, j-1)四次!据推测,这些 Cell 对象中的每一个都将彼此相等,但为什么不创建一次,并在后续调用中重用它:

Cell neighbour = new Cell(i-1, j-1);
if (map.get(neighbour) == null){
map.put(neighbour, ((Math.random()<0.5)?0:1));
sum += map.get(neighbour);
}
else{
sum += map.get(neighbour);
}

垃圾收集器现在会高兴一点。但我仍然看到 3 个对 map.get(neighbour) 的调用!为什么?最后两个是相同的... if 语句每个分支末尾的 sum += map.get(neighbour); 。如果我们将其从声明中移出,事情就会变得更好!

Cell neighbour = new Cell(i-1, j-1);
if (map.get(neighbour) == null){
map.put(neighbour, ((Math.random()<0.5)?0:1));
}
sum += map.get(neighbour);

这是一个相当大的改进。

(您可以使用computeIfAbsent()进一步减少代码,它会获取值,并在必要时创建它。如果需要,请随意研究它;您需要了解lambda。 )

每个相邻小区的代码都是相同的。因此,您可以将该代码放入其自己的函数中并调用它。

int sum = 0;
sum += neighbour_value(i-1, j-1);
sum += neighbour_value(i, j-1);
sum += neighbour_value(i+1, j-1);
... etc ...

希望有帮助。

祝你编码愉快。

关于java - 更新值时出现 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48615318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com