In a pinch you could use the PropertyChangeSupport
class. It makes managing propertyChanges
very easy. There's not much to tell here. The parties that want to listen for changes register their listener with the map. Then when the map modifies the value, the support fires off an event to all the listeners. The values that are returned in the Event class may be altered to ones chosing.
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashMap;
public class PropertyChangeDemo implements PropertyChangeListener {
public static void main(String[] args) {
// leave static context of main
new PropertyChangeDemo().start();
}
public void start() {
MyMap<String,Integer> map = new MyMap<>();
map.addMapListener(this);
map.put("B",20);
map.put("B",99);
map.put("A",44);
map.entrySet().forEach(System.out::println);
}
Prints
source = map
oldValue = null
newValue = 20
source = map
oldValue = 20
newValue = 99
source = map
oldValue = null
newValue = 44
A=44
B=99
A listener for demonstration.
public void propertyChange(PropertyChangeEvent pce) {
System.out.println("source = " + pce.getPropertyName());
System.out.println("oldValue = " + pce.getOldValue());
System.out.println("newValue = " + pce.getNewValue());
}
}
The modified class
class MyMap<K,V> extends HashMap<K,V> {
private PropertyChangeSupport ps = new PropertyChangeSupport(this);
// method to add listener
public void addMapListener(PropertyChangeListener pcl) {
ps.addPropertyChangeListener(pcl);
}
@Override
public V put(K key, V value) {
V ret = super.put(key,value);
ps.firePropertyChange("map", ret, value);
return ret;
}
}
Note: There may be issues that have been missed in this simple solution. Testing should be conducted before put into production use. For one, there are many different ways to set an Entry's
value. This only does it when put
is invoked, either by the user or indirectly by the map itself.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…