【问题标题】:Java ConcurrentModificationException when using list.remove()使用 list.remove() 时的 Java ConcurrentModificationException
【发布时间】:2014-05-14 14:11:06
【问题描述】:

我有一个名为removeSup 的方法,它应该从补充列表中删除对象Supplement。 这是方法的代码:

private static void removeSup(Supplement supToRemove, List<Supplement> listToRemoveFrom) {
   Iterator<Supplement> iterator = listToRemoveFrom.iterator();
                while(iterator.hasNext()){
                    if(iterator.next().equals(supToRemove)){
                        iterator.remove();
                    }
                }
}

有一个名为magazine 的类定义了补充列表。

public class Magazine {
  private List<Supplement> supList;
  public List<Supplement> getSupList() {
        return this.supList;
    }
  public void setSupList(List<Supplement> supList) {


      this.supList = supList;
        }
public Magazine(Double cost, String _name){
        this.supList = new ArrayList<>();
        this.weekCost = cost;
        this.name = _name;
    }
    }

supplement 类具有以下构造函数

public Supplement(String _name, Double _price, String _magName ){
        this.name=_name;
        this.price=_price;
        this.magName = _magName;
    }

在主类client 中有一个搜索,用户可以通过它来删除某个补充

private static void searchSup(){
   System.out.println("Search for Supplement");
        String search = scanner.nextLine();
        for (Supplement sup : magazine.getSupList()) {
            if (!sup.getSupName().equalsIgnoreCase(search)) {
         //do something
        }
        else{
              removeSup(sup,magazine.getSupList());
        }
    }

} 客户端类中的main方法如下:

 private Magazine magazine;
        public static void main(String[] args) {
                magazine = new Magazine(3.0, "pop");
                List<Supplement> startList = new ArrayList<>();
            startList.add(new Supplement("Nat Geo", 3.0,"pop"));
            startList.add(new Supplement("Discovery", 5.0,"pop"));
            startList.add(new Supplement("Health", 6.3,"pop"));
            startList.add(new Supplement("IT", 8.3,"pop"));
            magazine.setSupList(startList);
            searchSup();
        }

当我运行这个程序并输入任何添加的补充时,我得到一个错误

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at Client.searchSup(Client.java:131)
    at Client.searchSup(Client.java:140)
    at Client.main(Client.java:588)

是我用来搜索的 for 循环给了我一个错误吗?如果是这样,我将如何解决这个问题?

【问题讨论】:

  • 您是否阅读了有关 ConcurrentModificationException 的 javadoc?另外,您是否搜索过类似的问题?
  • 不要使用新的迭代器在removeSup 中再次遍历列表,而是使用searchSup 中的显式迭代器进行迭代,并在searchSup 中使用该迭代器的remove
  • @user2357112 有最好的答案 IMO
  • @user2357112 我尝试这样做并得到同样的错误。 `else{ 杂志.getSupList().remove(sup); } 喜欢吗?

标签: java arraylist iterator


【解决方案1】:
private static int indexOfSup(List<Supplement> supSearchList, String nameOfSup) {
        for (Supplement sup : supSearchList) {
            if (sup.getSupName().equalsIgnoreCase(nameOfSup)) {
                return supSearchList.indexOf(sup);
            }
        }
        return -1;
    }

然后我使用这个整数从列表中删除。 一个简单的List.Remove(index) 工作正常

感谢所有回复。

【讨论】:

  • 您确实做了很多 Java 可以为您做的工作。查看CollectionList 接口,特别是它们的remove() 方法以及如何为对象覆盖equals()
【解决方案2】:

它接缝“杂志”是main方法中的本地var,searchSup无法访问。修复它就像 私人无效搜索(杂志杂志) { //... } 如果您能提供更多详细信息,第 131 行和第 140 行中的代码会有所帮助。

【讨论】:

    【解决方案3】:

    您通常不应在迭代 Collection 时对其进行修改。修改元素很好,但您确实不应该在迭代时从Collection 中删除某些内容。见这里:http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html。此外,ConcurrentModificationException 的 Javadoc 可能会有所帮助。

    您可以尝试返回一个删除了Supplement 的新列表:

     private static List<Supplement> removeSup(Supplement supToRemove, List<Supplement> listToRemoveFrom) {
        List<Supplement> filteredSupplements = new ArrayList<Supplement>();
        for(Supplement supplement : listToRemoveFrom) {
           if(!suppplement.equals(supToRemove)){
               filteredSupplements.add(supplement);
           }
    
        }
    
        return filteredSupplements;
    }
    

    【讨论】:

    • 谢谢。有什么办法可以从列表中删除一个元素?
    • Collection 接口有一个 remove() 方法,但您需要阅读实现它的每个集合的 Javadoc。
    猜你喜欢
    • 2012-07-21
    • 1970-01-01
    • 2013-05-20
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 2013-06-04
    相关资源
    最近更新 更多