【问题标题】:ConcurrentModificationException for ArrayList while trying to add items in list [duplicate]尝试在列表中添加项目时 ArrayList 出现 ConcurrentModificationException [重复]
【发布时间】:2020-11-05 09:18:39
【问题描述】:

我有一个“购物车”按钮,用于查询 select * 并在 ArrayList 中添加项目(文章),因为我想避免每次单击按钮时都在列表中添加文章 我试过这个:

for(Article a : articleList){
     String checkId = "select * from article";
     PreparedStatement ps = conn.prepareStatement(checkId);
     ResultSet rs = ps.executeQuery(checkId);
     rs.next();
     if(a.getId()==rs.getInt("id")){
      //Here i'm returning list, just like it is in DataBase.
    } else{
        //Here i want to add articles in the list
    }
 }

我假设我遇到了那个异常,因为我在遍历同一个列表时在 ArrayList 中添加了文章。我该如何解决这个问题?

【问题讨论】:

  • 将它们添加到另一个List
  • 您只查看查询返回的第一行。也许你应该把你的 SQL 改成 'select count(*) from article where id = ?',然后 ps.setInteger(a.getId())

标签: java for-loop exception arraylist


【解决方案1】:

你的问题是流程代码

public static void main(String[] args) {
    List<Integer> integerList = new ArrayList<>();
    integerList.add(1);
    integerList.add(2);
    for (Integer integer : integerList) {
        integerList.add(3);
    }
}

错误在于

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:907)
    at java.util.ArrayList$Itr.next(ArrayList.java:857)
    at com.test.TestList.main(TestList.java:28)

我们可以使用 ListIterator 来添加值。代码是这样的

package com.test;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/**
 *
 *
 *
 *
 * @author shikai.liu
 * @version 1.0
 * @since JDK1.7
 */
public class TestList {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        integerList.add(2);
        // for (Integer integer : integerList) {
        // integerList.add(3);
        // }
        ListIterator<Integer> integerIterator = integerList.listIterator();
        while (integerIterator.hasNext()) {
            Integer integer = integerIterator.next();
            if (integer == 1)
                integerIterator.add(5);
        }

    }
}

所以你的代码是这样的

ListIterator<Article> integerIterator = articleList.listIterator();
        while (integerIterator.hasNext()) {
            Article a = integerIterator.next();
            String checkId = "select * from article";
            PreparedStatement ps = conn.prepareStatement(checkId);
            ResultSet rs = ps.executeQuery(checkId);
            rs.next();
            if(a.getId()==rs.getInt("id")){
                //Here i'm returning list, just like it is in DataBase.
            } else{
                //integerIterator.add()
                //Here i want to add articles in the list
            }
        }

【讨论】:

    【解决方案2】:

    正如已经指出的那样,您的假设是正确的。您将获得ConcurrentModificationException 用于在迭代列表时尝试修改列表。您只需要事先收集查询结果,然后遍历articleList

    我建议您使用Set 而不是List 来实现这些集合。这会更有效率,但您需要覆盖 Article equals()hashcode() 方法以保证正确比较。

    否则,您可以使用 Java 8 Stream.concat 连接两个 Lists,然后使用文章 ID 作为键对结果进行重复数据删除,将它们插入到 LinkedHashMap(以实现高效访问)。

    String checkId = "select * from article";
    PreparedStatement ps = conn.prepareStatement(checkId);
    ResultSet rs = ps.executeQuery();
    List<Article> dbArticles = new ArrayList<>();
    while(rs.next()) {
      dbArticles.add(
         Article.of(
            rs.getInt("id") 
            /* rs.get...retrieve all other attributes */
         )
      );
    }
    
    Collection<Article> result = Stream.concat(dbArticles.stream(), articleList.stream())
        .collect(Collectors.toMap(Article::getId, 
                 Function.identity(), 
                 (l, r) -> l, 
                 LinkedHashMap::new)
        ).values();
    

    【讨论】:

    • 感谢您的回答,但我需要学习流和 lambda 表达式,这样我才能阅读:D
    • 不要让不同的语法和一些新概念让您望而却步。例如,lambda (l, r) -&gt; l 表示一个函数,它获取 2 个参数(任何类型)并将返回左边的一个,here 是使用泛型的定义。在您的情况下,它用于决定当它们拥有相同的键时,哪个(键,值)对将保留在集合中。我想说最重要的是你在迭代集合时发现了改变集合的问题。干得好!
    • 好吧,我想我有一个想法,别担心,我不会拖延,这对我来说很重要,我的计划是在之后学习流、lambda 表达式和设计模式我完成了这家书店,再次感谢。我没有遍历 Arraylist 就解决了问题。
    猜你喜欢
    • 2019-05-12
    • 2012-01-01
    • 1970-01-01
    • 2012-04-06
    • 2021-12-15
    • 1970-01-01
    • 2017-07-19
    • 2018-05-25
    • 2017-07-17
    相关资源
    最近更新 更多