我对某事有点困惑。 Java的文档告诉我们,当使用Iterator对象迭代该集合时,从集合中删除项目时没有定义的行为,唯一安全的方法是使用Iterator.remove()。在遍历事件处理程序集合时,如何安全地从*回调中的*删除处理程序?
怎么那么,你会安全地删除从一个ArrayList事件处理程序,如果在通过列表迭代的过程中,处理程序的一个决定,是时候去掉自己作为一个监听?
// in public class Dispatcher
public void dispatchEvent(){
Iterator<IEventHandler> iterator = mHandlers.iterator();
IEventHandler handler = null;
while(iterator.hasNext()){
handler = iterator.next();
handler.onCallbackEvent();
}
}
public void insertHandler(IEventHandler h){
mHandlers.add(h);
}
public void removeHandler(IEventHandler h){
mHandlers.remove(h);
}
同时,处理程序被实例化这样的...
final Dispatcher d = new Dispatcher();
d.insertHandler(new IEventHandler(){
@Override
public void onCallbackEvent(){
Log.i(" callback happened ");
d.removeHandler(this);
}
});
看到潜在的问题?您删除从ArrayList中的处理程序为onCallbackEvent()的结果,在这特别的处理声明,而你还在使用迭代器迭代。
这是一个棘手的问题?处理这种情况的安全方法是什么?
谢谢你的建议。这确实不幸。我不得不想知道迭代器如果没有提供一种安全的方法来修改底层集合,那么迭代器有什么意义。 **注意:是的,我知道Iterator的设计模式。不过,似乎这种安全性是迭代器应该向你购买的东西,如果你麻烦去使用它的话。 – scriptocalypse 2011-03-04 23:38:09
为了让您在寻找迭代安全性,迭代器必须复制或执行同样计算密集的任务。你能想出另外一种方法来实现一个安全的迭代器吗?您必须复制更改或复制迭代。在大多数情况下,复制更改比较合适,因为更改频率低于迭代次数。默认集合不提供迭代安全性,因为并非所有情况都需要它。这就是为什么有ArrayList和CopyOnWriteArrayList。 – 2011-03-04 23:44:05
性能足够了。感谢您的洞察力! – scriptocalypse 2011-03-05 01:25:20