我有点需要关闭泛型类型X
和Y
的两个对象,并使用它来返回类型T
。我想将这些项目放在严密管理的HashMap
中,并使用它来查找X,Y键。
但是,如何确保X
和Y
在其内存引用上进行哈希编码和相等性比较,而不是重写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?
}
}
}
答案 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()中,您应首先检查两个对象是否具有相同的引用(使用==),然后检查您要比较的对象是否为空。之后,确保两个对象都是相同类型的实例。最后一步:检查两者的属性值是否相等。
如果你有一个超类,它将被认为是处理超类中前三个步骤的好方式。