亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我可以順序使用許多 listIterators 來改變或刪除 Java 中 ArrayList

我可以順序使用許多 listIterators 來改變或刪除 Java 中 ArrayList

慕哥9229398 2024-01-25 23:04:23
我依靠列表迭代器來移動字符列表。這是一個單線程程序,我在 4 種不同的方法中順序使用 listIterator 對象。每種方法都有相同的設置: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); // because its lucky    }}使用此模式,在第二個迭代器上將引發以下異常:java.util.ConcurrentModificationException但是,查看 javadocs,我在拋出的異常中沒有看到此異常,也沒有看到完成后關閉迭代器的方法。我是否錯誤地使用了 listIterator?我必須多次迭代同一個 ArrayList,每次都有條件地刪除或改變每個元素。也許有更好的方法來迭代 ArrayList,而 ListIterator 不能最好地解決這個用例。ListIterator 的 java 文檔
查看完整描述

3 回答

?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

javadoc中對此進行了解釋ArrayList,您正在使用以下命令remove()修改列表:set()Iterator

此類的iteratorlistIterator方法返回的迭代器是快速失敗的:如果在創建迭代器后的任何時間對列表進行結構修改,除了通過迭代器自己的刪除或添加方法之外的任何方式,迭代器將拋出ConcurrentModificationException.?因此,面對并發修改,迭代器會快速而干凈地失敗,而不是在未來不確定的時間冒任意、非確定性行為的風險。



查看完整回答
反對 回復 2024-01-25
?
慕雪6442864

TA貢獻1812條經驗 獲得超5個贊

當顯示的代碼顯然不是產生異常的代碼時,很難對問題進行診斷,因為它甚至無法編譯。remove的方法不Iterator接受參數,并且該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);

    }

}

會毫無問題地運行。您的一般問題的答案是,每次修改都會使所有現有迭代器無效,除了當您確實使用迭代器而不是直接使用集合接口進行修改時用于進行修改的迭代器。


但在您的代碼中,只有一個迭代器,它僅針對這一操作而創建和使用。只要不重復使用同一個集合的迭代器,就不會出現失效問題。無論如何,先前操作中存在的迭代器都會被放棄,并且后續操作中使用的迭代器還不存在。


盡管如此,它還是更容易使用


private void myMethod(ArrayList<Integer> input) {

    input.removeIf(in -> in < 10);

    input.replaceAll(in -> in*in);

}

反而。與原始代碼不同,這會執行兩次迭代,但正如本答案中所解釋的,removeIf在性能確實很重要的情況下,實際上會比基于迭代器的刪除更快。


但問題仍然存在。顯示的代碼不會導致ConcurrentModificationException,因此您的實際問題在其他地方,并且可能仍然存在,無論如何實現這一方法。


查看完整回答
反對 回復 2024-01-25
?
動漫人物

TA貢獻1815條經驗 獲得超10個贊

我對 Java ListIterators 的了解不夠,無法回答這個問題,但看來我在這里遇到了 XY 問題。使用 Java Streams 似乎可以更好地解決這個問題,即通過對原始 ArrayList 中的每個元素執行函數來刪除元素或將元素映射到新的 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;

    }


查看完整回答
反對 回復 2024-01-25
  • 3 回答
  • 0 關注
  • 217 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號