用于对象引用的Hashcode和Equals?

时间:2015-06-26 19:17:10

标签: java hashmap equals hashcode

我有点需要关闭泛型类型XY的两个对象,并使用它来返回类型T。我想将这些项目放在严密管理的HashMap中,并使用它来查找X,Y键。

但是,如何确保XY在其内存引用上进行哈希编码和相等性比较,而不是重写hashCode / equals的任何实现?

public final class BiReferenceCache<X,Y,T> { 
    private final HashMap<Key<X,Y>,T> cacheMap = new HashMap<>();

    public T get(X item1, Y item2) { 
        return cacheMap.get(new Key<X,Y>());
    }

    private static final class Key<X,Y> { 
        private final X val1;
        private final Y val2;

        Key(X val1, Y val2) { 
            this.val1 = val1;
            this.val2 = val2;
        }

        public int hashCode() { 
            //??? What do I do to hashcode by val1 and val2's memory reference?
        }
        public boolean equals(Object obj) { 
            //??? What do I do to check equality for val1 and val2's memory reference?
        }
    }

}

5 个答案:

答案 0 :(得分:4)

使用

System.identityHashCode

==

答案 1 :(得分:1)

您可以使用==检查内存标识,使用java.lang.System#identityHashCode(Object)获取非重写哈希码。

private static final class Key<X,Y> { 
    private final X val1;
    private final Y val2;

    Key(X val1, Y val2) { 
        this.val1 = val1;
        this.val2 = val2;
    }

    public int hashCode() { 
        return 31 * System.identityHashCode(val1) + System.identityHashCode(val2);
    }

    public boolean equals(Object obj) { 
        if (obj == null) {
            return false;
        }
        if (!obj instanceof Key) {
            return false;
        }
        Key other = (Key)obj;
        return val1 == other.val1 && val2 == other.val2;
    }
}

答案 2 :(得分:1)

==运算符是否应该断言引用相等?

此问题可能会回答您的hashCode问题:How do you get the "object reference" of an object in java when toString() and hashCode() have been overridden?(引自下文)

你打算用它做什么(你想做什么会影响你需要调用的东西)?

hashCode(),如Javadocs中所定义的那样:

  

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要此实现技术。)

因此,如果您正在使用hashCode来查明它是否是内存中的唯一对象,那么这不是一个好方法。

System.identityHashCode执行以下操作:

  

返回与默认方法hashCode()返回的给定对象相同的哈希码,无论给定对象的类是否覆盖hashCode()。空引用的哈希码为零。

对于你正在做的事情听起来像你想要的......但是你想要做的事情可能不安全,这取决于图书馆的实施方式。

答案 3 :(得分:0)

你应该使用hashCode:

val1.hashCode() + val2.hashCode();

和等于:

val1.equals(obj.val1) && val2.equals(obj.val2);

基本上转发责任。

PS:如果允许null,则必须添加适当的代码。

答案 4 :(得分:0)

对于hashCode(),你可以简单地使用:val1.hashCode()^ val2hashCode(); (按字节顺序XOR运算符^) - 不是一个很好的解决方案,但应该做它应该做的事情。

在equals()中,您应首先检查两个对象是否具有相同的引用(使用==),然后检查您要比较的对象是否为空。之后,确保两个对象都是相同类型的实例。最后一步:检查两者的属性值是否相等。

如果你有一个超类,它将被认为是处理超类中前三个步骤的好方式。