我對某事有點困惑。 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