繁体   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