【问题标题】:Concurrent Modification Exception while adding elements to ArrayList recursively递归添加元素到 ArrayList 时并发修改异常
【发布时间】:2020-08-17 08:27:36
【问题描述】:

递归添加元素到 ArrayList 时出现并发修改异常。

import java.util.*;

public class Hello {

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        
        System.out.println(gss(str));
    }

    public static ArrayList<String> gss(String str) {
        if(str.length() == 0){
            ArrayList<String> list = new ArrayList<String>();
            list.add("");
            return list;
        }
        
        ArrayList<String> list = gss(str.substring(1));
        for(String temp : list){
            list.add(str.charAt(0)+temp);  // Problem  
        }
        
        return list;
    }

}

【问题讨论】:

  • 您需要通过添加list.addAll(list.stream().map(temp -&gt; str.charAt(0)+temp).collect(Collectors.toList()));来避免并发修改
  • 您确定要向列表中添加新元素而不是修改它们吗?
  • 是的。 @Amongalen
  • 你能提供一个输入和预期输出的例子吗?
  • 这与递归无关。您根本无法添加到您正在迭代的列表中。

标签: java recursion arraylist collections subsequence


【解决方案1】:

解决方案:在每个调用堆栈处形成一个新的 ArrayList 并返回它。

import java.io.*;

import java.util.*;

public class Main {

public static void main(String[] args) throws Exception {
    Scanner sc = new Scanner(System.in);
    String str = sc.next();
    
    System.out.println(gss(str));
}

public static ArrayList<String> gss(String str) {
    if(str.length() == 0){
        ArrayList<String> list = new ArrayList<String>();
        list.add("");
        return list;
    }
    
    ArrayList<String> list = gss(str.substring(1));
    ArrayList<String> listToReturn = new ArrayList<>();
    
    for(String temp : list){
        listToReturn.add(temp);
    }
    for(String temp : list){
        listToReturn.add(str.charAt(0) + temp);    
    }
    
    return listToReturn;
}

}

我最近遇到了这个blog

也就是说,它使用了一个名为modCount 的瞬态变量,它跟踪列表在结构上被修改了多少次。结构修改是改变列表大小的修改,这可能会影响迭代的进度,并可能产生不正确的结果。 IteratorListIterator 都使用此字段来检测意外更改。 List 的其他结构修改 List 的方法也使用此方法,例如add(), remove().

原因:ConcurrentModficationException的真正原因是不一致modCount。当您迭代ArrayList 时,迭代器的next() 方法会跟踪modCount。如果您通过添加或删除元素来修改集合,则 modCount 将发生变化,并且与预期的 modCount 不匹配,因此迭代器将抛出 ConcurrentModificationException

【讨论】:

  • 你可以listToReturn.addAll(list)
猜你喜欢
  • 2011-10-15
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 2012-12-24
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多