Here's my complete wrapper. It's rather simplistic and could probably use 
some optimization in .equals, but I didn't try an awful lot.

Comments welcome.

/**
 * A wrapper of HashMap that support recursion in values (can contain itself 
as a value) and still calculate
 * hashCode and equals correctly.
 */
public  class FixedHashMap<K,V> extends HashMap<K,V> {
    protected boolean _inHashCode = false;
    protected HashSet<FixedHashMap<?,?>> _inEqualsWith = new 
HashSet<FixedHashMap<?,?>>();
    
    @Override
    public int hashCode() {
        int result = 0;
        if (_inHashCode ) { return result; }
        _inHashCode = true;
        result = super.hashCode();
        _inHashCode = false;
        return result;
    }
    
    /**
     * Equals needs to fix the case of comparing two recursive maps. The 
rest is handled by the default implementation. 
     */
    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (null == other) {
            return false;
        }
        if (!(other instanceof HashMap)) {
            return false;
        }
        if (!(other instanceof FixedHashMap)) {
            // We assume other is a non-recursive map,
            // and the default .equals doesn't recurse infinitely 
            return super.equals(other);
        }
        // It may be a recursive map.
        FixedHashMap<?, ?> savedOther = (FixedHashMap<?, ?>) other;
        if (this._inEqualsWith.contains(savedOther)) {
            // We are already comparing ourselves with this object!
            // Return 'true' because the final result will be the 
conjunction ('and')
            // of this result and all the other entries. If all the other 
entries are equal,
            // we can say the maps are equal.
            return true;
        }
        this._inEqualsWith.add(savedOther);
        boolean res = super.equals(other);
        this._inEqualsWith.remove(savedOther);
        return res;
    }
}

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to