2

注意:我不知道 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 是否会删除该元素。这是我的数据结构需要处理的例外情况。

第二部分=>制作一个智能监听器通知器以避免到处重复代码

4

3 回答 3

3

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--;
    }
}

这仅在删除的项目是最后检查的项目时才有效。对于列表的其他更改,您将不得不有更复杂的逻辑。

于 2012-08-24T22:11:05.283 回答
2

我应该使用什么数据结构来允许迭代并有可能删除?

最简单的选择是获取列表的副本并对其进行迭代:

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

现在,是否有任何东西从原始列表中删除了一个想法并不重要——这不会改变列表的副本。

另一种选择是使用CopyOnWriteArrayList. 然后,您可以随意迭代并删除或添加项目:

“快照”样式的迭代器方法使用对创建迭代器时数组状态的引用。这个数组在迭代器的生命周期内永远不会改变,所以干扰是不可能的,并且迭代器保证不会抛出 ConcurrentModificationException。自创建迭代器以来,迭代器不会反映对列表的添加、删除或更改。

于 2012-08-24T22:17:47.967 回答
0

我认为你应该改变你doSomething()。如果可以从中mo.doSomething()删除,你必须知道你的。molmol

您可以像这样更改代码:

在您的 MyObj 中创建一个有效标志。仅在有效时才收听。

while(list.hasNext()) {
   MyObj mo = list.next()
   if(mo.isValid()){
       mo.doSomething();
   } else {
       list.remove();
   }
}
于 2012-08-24T22:25:56.967 回答