【问题标题】:Running into java.util.ConcurrentModificationException while iterating list迭代列表时遇到 java.util.ConcurrentModificationException
【发布时间】:2013-05-17 21:27:48
【问题描述】:

我正在尝试将记录列表拆分为记录子列表。我成功地将列表拆分为子列表,我想查看子列表的内容,但不知何故我一直遇到这个 ConcurrentModificationException。

我的拆分方法:

/**
     * @param list - list of results
     * @param size - how many sublists
     * @return ret - returns a list containing the sublists
     * */
    public static <T> List<List<T>> split(List<T> list, int size) throws NullPointerException, IllegalArgumentException {
        if (list == null) {
            throw new NullPointerException("The list parameter is null.");
        }
        if (size <= 0) {
            throw new IllegalArgumentException("The size parameter must be more than 0.");
        }

        int recordsPerSubList = list.size() / size; // how many records per sublist
        List<List<T>> sublists = new ArrayList<List<T>>(size); // init capacity of sublists

        // add the records to each sublist
        for (int i=0; i<size; i++) {
            sublists.add(i, list.subList(i * recordsPerSubList, (i + 1) * recordsPerSubList));
        }

        // for the remainder records, just add them to the last sublist
        int mod = list.size() % recordsPerSubList;
        if (mod > 0) {
            int remainderIndex = list.size() - mod;
            sublists.get(size - 1).addAll(list.subList(remainderIndex, list.size()));
        }

        return sublists;
    }

我在这里称呼它:

List<List<QuoteSearchInfo>> ret = Util.split(quoteSearchInfoList, 5);

            int fileCounter = 0;
            for (List<QuoteSearchInfo> sublist : ret) {
                fileCounter++;

                String sublistJson = new Gson().toJson(sublist);
                filename = JSON_FILE_NAME + fileCounter + JSON_FILE_END;
                saveToFile(filename, sublistJson);
                AWSManager.getInstance().uploadQuoteSearchJson(filename);
            }

^ 在这里,我尝试将列表拆分为子列表,以便将它们上传到 S3。

和堆栈跟踪:

java.util.ConcurrentModificationException 
at java.util.SubList.checkForComodification(AbstractList.java:752) 
at java.util.SubList.listIterator(AbstractList.java:682) 
at java.util.AbstractList.listIterator(AbstractList.java:284) 
at java.util.SubList.iterator(AbstractList.java:678) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:95) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60) 
at com.google.gson.Gson.toJson(Gson.java:546)
at com.google.gson.Gson.toJson(Gson.java:525) 
at com.google.gson.Gson.toJson(Gson.java:480) 
at com.google.gson.Gson.toJson(Gson.java:460) 
at com.crover.QuoteSearchRover.execute(QuoteSearchRover.java:41) 
at com.crover.CroverMain.execute(CroverMain.java:85) 
at com.crover.CroverMain.main(CroverMain.java:35)

【问题讨论】:

  • 发布异常堆栈跟踪。
  • @Pangea 补充说,当我尝试 gson 列表时似乎出了点问题。
  • 这个异常通常意味着列表在被迭代时被修改。 GSON 在幕后做了什么?此外,您可能希望将公司名称更改为不同的名称。
  • @ZiyaoWei 公司名称?
  • @ZiyaoWei 哈哈,谢谢!没听懂。

标签: java list concurrentmodification


【解决方案1】:
sublists.get(size - 1).addAll(list.subList(remainderIndex, list.size()));

sublists.get(size - 1) 是列表子范围的实时视图,因此当您向其中添加元素时,您也在将元素添加到原始列表中,同时您试图将元素取出来自list.subList。通常,您无法在迭代列表时对其进行修改。

最简单的解决方案是不将元素添加到sublists.get(size - 1),而只是更新它:

sublists.set(size - 1, 
   list.subList(remainderIndex - recordsPerSublist, list.size()));

【讨论】:

  • 目前在我的代码中,我将有 5 个列表,其中前 4 个列表的长度相同。最后一个(第 5 个)列表将包含其他列表的长度以及任何剩余记录。该代码不会取代第 5 个列表吗?
  • 这看起来像答案,但堆栈跟踪说异常不会发生在 split 方法中;有cmets吗?
猜你喜欢
  • 2015-01-14
  • 1970-01-01
  • 2013-06-02
  • 2019-03-08
  • 2021-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
相关资源
最近更新 更多