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