簡體   English   中英

我無法弄清楚這個ConcurrentModificationException

[英]I can't figure out this ConcurrentModificationException

我覺得我的Java生銹了,所以我嘗試了一個簡單的問題:使用Linked Lists進行合並排序,只返回唯一值。 以下是我的第一次嘗試之一。 這對我來說很有意義。 問題是,無論我做了什么,我總是得到一個ConcurrentModificationException

我嘗試過的事情包括:

  • 使塊或方法synchronized
  • sort方法中的迭代器替換LinkedLists。
  • 在單獨的變量中跟蹤列表的大小(該部分留在其中)。

沒有任何效果。 ConcurrentModificationsException移動到其他地方但它仍然存在。 我真的不確定為什么。 我怎樣才能解決這個問題?

在此特定嘗試中,在調用addAll時發生異常。 我將列表中的所有操作都放在了自己的塊中,但Java顯然並不關心。

package com.regularoddity.dotcloud;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class Merge {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<Integer> myList = new LinkedList<Integer>();
        myList.add(2);
        myList.add(9);
        myList.add(1);
        myList.add(3);
        myList.add(8);
        myList.add(7);
        myList.add(1);
        myList = sort(myList);
        Iterator<Integer> lit = myList.iterator();
        while(lit.hasNext()) System.out.printf("%s ", lit.next());
    }

    private static List<Integer> merge(List<Integer> list1, List<Integer> list2) {
        List<Integer> result = new LinkedList<Integer>();
        int size1 = list1.size();
        int size2 = list2.size();
        {
            while (size1 > 0 && size2 > 0) {
                if (list1.get(0) == list2.get(0)) {
                    result.add(list1.remove(0));
                    list2.remove(0);
                    size1--; size2--;
                }
                else if (list1.get(0) <= list2.get(0))
                {
                    result.add(list1.remove(0));
                    size1--;
                }
                else
                {
                    result.add(list2.remove(0));
                    size2--;
                }
            }
        }
        result.addAll(list1);
        result.addAll(list2);
        return result;
    }

    private static List<Integer> sort(List<Integer> list) {
        int lsize = list.size();
        if (lsize <= 1) return list;
        int pivot = lsize / 2;
        List<Integer> list1 = list.subList(0, pivot);
        List<Integer> list2 = list.subList(pivot, lsize);
        list1 = sort(list1);
        list2 = sort(list2);
        return merge(list1, list2);
    }


}

令我感到困惑的是我從未明確地與列表進行交互。 必須有一個隱式迭代,但我似乎無法將其分解出來。

編輯:我沒有包括堆棧跟蹤,因為我(愚蠢地)認為,因為它改變了每次修復的嘗試,它將沒有用。 但是,實際上,它沒有太大變化。 這是當前實現的堆棧跟蹤:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.SubList.checkForComodification(AbstractList.java:752)
    at java.util.SubList.size(AbstractList.java:625)
    at com.regularoddity.dotcloud.Merge.merge(Merge.java:30)
    at com.regularoddity.dotcloud.Merge.sort(Merge.java:64)
    at com.regularoddity.dotcloud.Merge.sort(Merge.java:62)
    at com.regularoddity.dotcloud.Merge.main(Merge.java:23)

com.regularoddity.dotcloud.Merge.main(Merge.java:23)

的javadoc的subList指出:

如果支持列表(即此列表)在結構上以除返回列表之外的任何方式進行修改,則此方法返回的列表的語義將變為未定義。

在您的情況下,您調用subList兩次並通過兩個子列表修改原始列表。 這是你的例外的來源。

在不改變代碼的情況下,您可以簡單地制作副本以避免出現此問題:

List<Integer> list1 = new LinkedList<> (list.subList(0, pivot));
List<Integer> list2 = new LinkedList<> (list.subList(pivot, lsize));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM