On Monday, January 3, 2011 10:42:28 AM UTC+1, sinelaw wrote: > > Thomas - Also, regarding your suggestions the wrapper object is in > fact what I'm using for now (my second post mentioned that).
You're subclassing HashMap, not wrapping a Map. But I > don't see how a sentinel would help me in my real use case of a > complex graph of circular references between maps, since it will be > hard to keep track of which sentinel represents which map. > yes, sorry I misread your initial 4-lines repro case. So , I think you'd to use a wrapper object that implements equals and hashCode independently of the content of the wrapped map; something like: // do not implement Map, as it would break the contract for Map.hashCode and Map.equals class Wrapper<K, V> { private final Map<K, V> map; public Wrapper(Map<K,V> map) { this.map = map; } public final Map<K, V> get() { return map; } @Overrides public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof Wrapper) { // use identity comparison: 2 wrappers are equal if they wrap the very same map, independently of its content return map == ((Wrapper) obj).map; } return false; } @Overrides public int hashCode() { // not the best for performances, but at least does not violates the Object.hashCode/equals contract return 31; } } Best would probably be to use a subclass of Map that keeps a reference to the "key" object so as to maintain a 1:1 bidirectional relationship between maps and their keys (and that way, you don't even have to implement the hashCode and equals methods, the default implementations are sufficient): class MapWithKey<K, V> extends HashMap<K, V> { public final class Key<K, V> { public MapWithKey<K, V> getMap() { return MapWithKey.this; } } private final Key<K, V> key = new Key<K, V>(); public final Key<K, V> getKey() { return key; } } Then, instead of testMap2.put(testMap, null), you'd use testMap2.put(testMap.getKey(), null); -- http://groups.google.com/group/Google-Web-Toolkit-Contributors