Java:在这种特殊情况下,如何处理ConcurrentModificationException?
在我发布这个问题之前,我阅读了中的帖子。但对于这个特殊的问题,我真的不知道如何应用同样的哲学 在下面的问题中,我的变量Java:在这种特殊情况下,如何处理ConcurrentModificationException?,java,exception,arraylist,Java,Exception,Arraylist,在我发布这个问题之前,我阅读了中的帖子。但对于这个特殊的问题,我真的不知道如何应用同样的哲学 在下面的问题中,我的变量graph具有以下结构:HashMap。 和u和v具有类型int。基本上,我想删除数组列表中键值为I的值v,其中I出现在v的数组列表中 因此,如果整数i出现在v的arraylist中,我们在图中获得i的arraylist,并从中删除值v 这听起来很复杂。但我现在被这个ConcurrentModificationException困扰了一段时间 public int random_
graph
具有以下结构:HashMap
。
和u
和v
具有类型int
。基本上,我想删除数组列表中键值为I
的值v
,其中I
出现在v
的数组列表中
因此,如果整数i
出现在v
的arraylist中,我们在图中获得i
的arraylist,并从中删除值v
这听起来很复杂。但我现在被这个ConcurrentModificationException困扰了一段时间
public int random_contraction_algo(){
while(graph.size() > 2){
int u = select_remaining_edges_at_random(new ArrayList<Integer> (graph.keySet()));
int v = select_remaining_edges_at_random(graph.get(u));
merge(u,v);
}
return -1;
}
// select a pair of vertices from an edge
public int select_remaining_edges_at_random(ArrayList<Integer> vertices){
int index = (int)(Math.random() * (vertices.size()));
return vertices.get(index);
}
public void merge(int u, int v){
graph.get(u).addAll(graph.get(v));
// remove self-loops
graph.get(u).removeAll(Collections.singleton(u));
graph.get(u).removeAll(Collections.singleton(v));
// make sure all the edges of v are connected to u instead v
for(Iterator<Integer> iterator = graph.get(v).iterator(); iterator.hasNext();){
Integer i = iterator.next();
graph.get(i).remove((Integer) v);
graph.get(i).add(u);
}
// remove key
graph.remove(v);
}
从循环之前的列表中明确删除
v
:graph.get(v)。删除(v)
List=graph.get(v);
列表。删除(v);
for(整数i:列表){
图.获取(i).删除(v)
}
从循环前的列表中明确删除v
:graph.get(v).Remove(v)
List=graph.get(v);
列表。删除(v);
for(整数i:列表){
图.获取(i).删除(v)
}
问题在于当v==i
时,您正在修改与迭代相同的列表
一个简单的解决方案是防范这种情况:
for(Iterator<Integer> it = graph.get(v).iterator(); it.hasNext();) {
Integer i = it.next();
if (i == v) {
it.remove();
} else {
graph.get(i).remove((Integer) v);
}
}
for(Iterator it=graph.get(v.Iterator();it.hasNext();){
整数i=it.next();
如果(i==v){
it.remove();
}否则{
graph.get(i).remove((整数)v);
}
}
问题在于当v==i
时,您正在修改与迭代相同的列表
一个简单的解决方案是防范这种情况:
for(Iterator<Integer> it = graph.get(v).iterator(); it.hasNext();) {
Integer i = it.next();
if (i == v) {
it.remove();
} else {
graph.get(i).remove((Integer) v);
}
}
for(Iterator it=graph.get(v.Iterator();it.hasNext();){
整数i=it.next();
如果(i==v){
it.remove();
}否则{
graph.get(i).remove((整数)v);
}
}
我可能误解了你的意思。但是如果你不同意的话
因此,如果整数i出现在v的arraylist中,我们得到图中i的arraylist,并从中移除值v
这就是你想做的吗
HashMap<Integer, ArrayList<Integer>> graph = new HashMap<Integer, ArrayList<Integer>>();
for (int i = 0; i < 100; i++) {
graph.put(i, new ArrayList<Integer>());
}
int i = 0; // change value to whatever
int v = 0; // change value to whatever
if (graph.get(v).contains(i)) {
graph.get(i).remove(new Integer(v));
}
HashMap graph=newhashmap();
对于(int i=0;i<100;i++){
put(i,newarraylist());
}
int i=0;//将值更改为任意值
int v=0;//将值更改为任意值
if(图get(v)包含(i)){
graph.get(i).remove(新整数(v));
}
如果不是,你可以试着解释清楚你需要什么
编辑:
我认为这应该奏效:
HashMap<Integer, ArrayList<Integer>> graph = new HashMap<Integer, ArrayList<Integer>>();
for (int i = 0; i < 100; i++) {
graph.put(i, new ArrayList<Integer>());
}
int v = 0; // change value to whatever
int u = 0;
ArrayList<Integer> list = new ArrayList<Integer>(graph.get(v));
for(Integer i : list){
if(graph.get(i).contains(v)){
graph.get(i).remove(new Integer(v));
graph.get(i).add(u);
}
}
HashMap graph=newhashmap();
对于(int i=0;i<100;i++){
put(i,newarraylist());
}
int v=0;//将值更改为任意值
int u=0;
ArrayList=newArrayList(graph.get(v));
for(整数i:列表){
if(图get(i)包含(v)){
graph.get(i).remove(新整数(v));
图.get(i).add(u);
}
}
这将创建所讨论的ArrayList
的副本,因此我们从不在地图上迭代,从而可以对地图进行编辑
告诉我它是否有效。我可能误解了你的意思。但是如果你不同意的话 因此,如果整数i出现在v的arraylist中,我们得到图中i的arraylist,并从中移除值v 这就是你想做的吗
HashMap<Integer, ArrayList<Integer>> graph = new HashMap<Integer, ArrayList<Integer>>();
for (int i = 0; i < 100; i++) {
graph.put(i, new ArrayList<Integer>());
}
int i = 0; // change value to whatever
int v = 0; // change value to whatever
if (graph.get(v).contains(i)) {
graph.get(i).remove(new Integer(v));
}
HashMap graph=newhashmap();
对于(int i=0;i<100;i++){
put(i,newarraylist());
}
int i=0;//将值更改为任意值
int v=0;//将值更改为任意值
if(图get(v)包含(i)){
graph.get(i).remove(新整数(v));
}
如果不是,你可以试着解释清楚你需要什么
编辑:
我认为这应该奏效:
HashMap<Integer, ArrayList<Integer>> graph = new HashMap<Integer, ArrayList<Integer>>();
for (int i = 0; i < 100; i++) {
graph.put(i, new ArrayList<Integer>());
}
int v = 0; // change value to whatever
int u = 0;
ArrayList<Integer> list = new ArrayList<Integer>(graph.get(v));
for(Integer i : list){
if(graph.get(i).contains(v)){
graph.get(i).remove(new Integer(v));
graph.get(i).add(u);
}
}
HashMap graph=newhashmap();
对于(int i=0;i<100;i++){
put(i,newarraylist());
}
int v=0;//将值更改为任意值
int u=0;
ArrayList=newArrayList(graph.get(v));
for(整数i:列表){
if(图get(i)包含(v)){
graph.get(i).remove(新整数(v));
图.get(i).add(u);
}
}
这将创建所讨论的ArrayList
的副本,因此我们从不在地图上迭代,从而可以对地图进行编辑
告诉我它是否有效。我认为这不会是一个问题,除非I==v,但是你可以使用标准迭代器方法。你能给我一个例子吗?修改循环中的其他列表不会是一个问题。如果下面两种解决方案中的任何一种仍然出现异常,那么它是由您的帖子中未包含的某些代码引起的@Ordous的解决方案也可能失败,如果您将相同的列表存储在地图中的不同键下。我的问题对此免疫(但效率稍低,因为它需要对列表进行一次附加扫描)。我将再次编辑这个问题,因为我想向你们展示更多的代码,这涉及到一个外部循环。请看UPDATE@mynameisJEFF您是否有可能给出一个失败的小数据示例?比如2-3个有边的节点?我已经尝试了3个节点,每个节点都相互连接,效果很好(如果没有显式的自循环移除,则会引发异常)。我认为这不会是问题,除非I==v,但是您可以使用标准迭代器方法。您能给我举个例子吗?修改循环中的其他列表不会是问题。如果下面两种解决方案中的任何一种仍然出现异常,那么它是由您的帖子中未包含的某些代码引起的@Ordous的解决方案也可能失败,如果您将相同的列表存储在地图中的不同键下。我的问题对此免疫(但效率稍低,因为它需要对列表进行一次附加扫描)。我将再次编辑这个问题,因为我想向你们展示更多的代码,这涉及到一个外部循环。请看UPDATE@mynameisJEFF你有没有可能给出一个小数据表