簡體   English   中英

遍歷列表並允許其同時刪除項目(NOT ITERATOR)

[英]Iterating through a list and allowing it to have an item removed at the same time (NOT ITERATOR)

注意:我不知道doSomething是否會刪除該元素。 這是我的數據結構需要處理的特例。

我的問題很簡單:

int size = list.size();
for(int i = 0; i < size; i++) {
   MyObj mo = list.get(i);
   mo.doSomething();
}

現在,如果doSomething()從列表中刪除mo,我最終將得到一個ArrayIndexOutOfBounds,因為列表現在已經縮小了。

我應該使用哪種數據結構來允許迭代並可以刪除? 我不能在這里使用迭代器,換句話說,我不能使doSomething返回一個布爾值並調用iterator.remove()。 數據結構必須以某種方式處理這種情況,並繼續迭代仍然存在的其余元素。

編輯:我不知道doSomething是否將刪除元素。 這是我的數據結構需要處理的特例。

第二部分 =>創建一個聰明的偵聽器通知程序,以避免到處都有代碼重復

例如,只要在刪除某些內容時更新索引和大小,就可以使用ArrayList

List<MyObj> list = new ArrayList<MyObj>();
int size = list.size();
for(int i = 0; i < size; i++) {
    MyObj mo = list.get(i);
    mo.doSomething();
    if (size > list.size()) {
        size = list.size();
        i--;
    }
}

僅當刪除的項目是最后檢查的項目時,此方法才有效。 對於列表的其他更改,您將必須具有更復雜的邏輯。

我應該使用哪種數據結構來允許迭代並可以刪除?

最簡單的方法是取單的副本,並遍歷不是:

List<MyObj> copy = new ArrayList<MyObj>(list);
for (MyObj mo : copy) {
    mo.doSomething();
}

現在,是否有任何東西從原始列表中刪除一個想法都沒關系-不會更改列表的副本。

另一種選擇是使用CopyOnWriteArrayList 然后,您可以隨意迭代和刪除或添加項目:

“快照”樣式的迭代器方法在創建迭代器時使用對數組狀態的引用。 此數組在迭代器的生命周期內永不更改,因此不可能發生干擾,並且保證迭代器不會引發ConcurrentModificationException。 自創建迭代器以來,該迭代器將不會反映對列表的添加,刪除或更改。

我認為您應該更改doSomething() 如果mo.doSomething()可以刪除mol ,你mo要知道你l

您可以像這樣更改代碼:

在您的MyObj內部創建一個有效的標志。 僅在有效時收聽。

while(list.hasNext()) {
   MyObj mo = list.next()
   if(mo.isValid()){
       mo.doSomething();
   } else {
       list.remove();
   }
}

暫無
暫無

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

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