3 回答

TA貢獻(xiàn)1993條經(jīng)驗(yàn) 獲得超6個(gè)贊
javadoc中對(duì)此進(jìn)行了解釋ArrayList
,您正在使用以下命令remove()
修改列表:set()
Iterator
此類的
iterator
和listIterator
方法返回的迭代器是快速失敗的:如果在創(chuàng)建迭代器后的任何時(shí)間對(duì)列表進(jìn)行結(jié)構(gòu)修改,除了通過(guò)迭代器自己的刪除或添加方法之外的任何方式,迭代器將拋出ConcurrentModificationException
.?因此,面對(duì)并發(fā)修改,迭代器會(huì)快速而干凈地失敗,而不是在未來(lái)不確定的時(shí)間冒任意、非確定性行為的風(fēng)險(xiǎn)。

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
當(dāng)顯示的代碼顯然不是產(chǎn)生異常的代碼時(shí),很難對(duì)問(wèn)題進(jìn)行診斷,因?yàn)樗踔翢o(wú)法編譯。remove的方法不Iterator接受參數(shù),并且該set方法是在 上定義的,但您的代碼僅ListIterator將變量聲明為。iIterator
固定版本
private void myMethod(ArrayList<Integer> input) {
ListIterator<Integer> i = input.listIterator();
while (i.hasNext()) {
Integer in = i.next();
if (in < 10)
i.remove();
else
i.set(in*in);
}
}
會(huì)毫無(wú)問(wèn)題地運(yùn)行。您的一般問(wèn)題的答案是,每次修改都會(huì)使所有現(xiàn)有迭代器無(wú)效,除了當(dāng)您確實(shí)使用迭代器而不是直接使用集合接口進(jìn)行修改時(shí)用于進(jìn)行修改的迭代器。
但在您的代碼中,只有一個(gè)迭代器,它僅針對(duì)這一操作而創(chuàng)建和使用。只要不重復(fù)使用同一個(gè)集合的迭代器,就不會(huì)出現(xiàn)失效問(wèn)題。無(wú)論如何,先前操作中存在的迭代器都會(huì)被放棄,并且后續(xù)操作中使用的迭代器還不存在。
盡管如此,它還是更容易使用
private void myMethod(ArrayList<Integer> input) {
input.removeIf(in -> in < 10);
input.replaceAll(in -> in*in);
}
反而。與原始代碼不同,這會(huì)執(zhí)行兩次迭代,但正如本答案中所解釋的,removeIf在性能確實(shí)很重要的情況下,實(shí)際上會(huì)比基于迭代器的刪除更快。
但問(wèn)題仍然存在。顯示的代碼不會(huì)導(dǎo)致ConcurrentModificationException,因此您的實(shí)際問(wèn)題在其他地方,并且可能仍然存在,無(wú)論如何實(shí)現(xiàn)這一方法。

TA貢獻(xiàn)1815條經(jīng)驗(yàn) 獲得超10個(gè)贊
我對(duì) Java ListIterators 的了解不夠,無(wú)法回答這個(gè)問(wèn)題,但看來(lái)我在這里遇到了 XY 問(wèn)題。使用 Java Streams 似乎可以更好地解決這個(gè)問(wèn)題,即通過(guò)對(duì)原始 ArrayList 中的每個(gè)元素執(zhí)行函數(shù)來(lái)刪除元素或?qū)⒃赜成涞叫碌?ArrayList 中。
private ArrayList<Integer> myMethod(ArrayList<Integer> input) {
ArrayList<Integer> results = input.stream().filter(
in -> (in < 10)).collect(Collectors.toCollection(ArrayList::new));
results = input.stream().map(
in -> in*in).collect(Collectors.toCollection(ArrayList::new));
return results;
}
添加回答
舉報(bào)