[英]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()
可以删除mo
从l
,你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.