我已经为一组通用侦听器实现了抽象通用提供程序E
,后代必须notifyListener(E)
用特定的通知代码覆盖。对于我选择的听众后备名单WeakHashMap<K,V>
。侦听器必须作为弱引用:
abstract public class NotificationProvider<E> {
private Map<E, Object> listeners = new WeakHashMap<E, Object>();
public addListener(E listener) {
listeners.put(listener, null);
}
public void notifyListeners() {
for (E listener: listeners.keySet())
notifyListener(listener);
}
abstract protected void notifyListener(E listener);
}
典型用途:
NotificationProvider<MyListener> provider;
provider = new NotificationProvider<MyListener>() {
@Override
protected void notifyListener(MyListener listener) {
listener.myNotification();
}
}
provider.addListener(myListener1);
provider.addListener(myListener2);
provider.notifyListeners();
一切正常,但是当我需要AbstractList
后代类作为侦听器时,支持WeakHashMap
只接受一个侦听器实例!很明显——方法hashCode()
和equals()
监听器为所有实例(空列表)返回相同的值,所以WeakHashMap.put
只替换以前添加的监听器。
public class MyList extends AbstractList<MyItem> {
// some implementation
}
NotificationProvider<MyList> provider;
provider = new NotificationProvider<MyList>() {
@Override
protected void notifyListener(MyList listener) {
// some implementation
}
}
MyList list1 = new MyList();
MyList list2 = new MyList();
provider.addListener(list1);
provider.addListener(list2);
provider.notifyListeners(); // only list2 instance is notified
什么是最好的解决方案?
使用另一个非 hashCode 支持集合——但
WeakHashMap
对我来说太棒了,因为自动为我管理弱引用使用非通用监听器,例如具有简单
equals() { return (this == object); }
实现的抽象类——但这不是那么灵活addListener(E)
使用简单的 equals() 为侦听器使用一些包装器——但由于弱引用,此包装器对调用者不能透明
另一个想法?