[英]concurrent modification exception on using addall and removeall on same arraylist
我必須從ArrayList
刪除一個子列表,並在開始時添加相同的子列表。 我正在使用以下代碼-
for(int i =0 ;i <m ; i++){
List<Integer> t = q.subList(j, k);
q.removeAll(t);
q.addAll(0, t);
}
我正在對addAll
並發異常修改。 我嘗試從q創建一個副本列表,然后在其上調用addAll
,但仍然在同一行上引發錯誤。
for(int i =0 ;i <m ; i++){
List<Integer> t = q.subList(j, k);
q.removeAll(t);
ArrayList<Integer> q1= new ArrayList<Integer>(q);
q1.addAll(0, t);
}
如何在同一數據列表上執行這兩項操作?
subList
的Javadoc指出:
如果后備列表(即此列表)以結構方式(而不是通過返回的列表)進行了修改,則此方法返回的列表的語義將變得不確定。 (結構修改是指更改此列表的大小的結構修改,或者以其他方式干擾此列表的方式,即正在進行的迭代可能會產生錯誤的結果。)
這意味着調用removeAll
可能會使subList
返回的列表無效。
另外, addAll
的Javadoc指出:
如果在操作進行過程中修改了指定的集合,則此操作的行為是不確定的。 ( 請注意,如果指定的集合是此列表,並且是非空的,則會發生這種情況 。)
在您的情況下,您傳遞給addAll
的Collection
是子列表,該子列表由要在其上調用addAll
的原始List
提供addAll
。
您可以做的是將子列表的元素存儲在單獨的List
( copyOfSubList
)中,使用clear()
刪除子列表的元素(這也會從原始List
刪除它們),然后添加元素將copyOfSubList
返回到原始List
:
for(int i =0 ;i < m ; i++) {
List<Integer> t = q.subList(j, k);
List<Integer> copyOfSubList = new ArrayList<> (t);
t.clear ();
q.addAll(0, copyOfSubList);
}
您可以使用CopyOnWriteArrayList
而不是ArrayList
。 CopyOnWriteArrayList
迭代器從不會拋出ConcurrentModificationException
。 創建迭代器后,它將保留列表內容的副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.