繁体   English   中英

哈希码和等于对象引用?

[英]Hashcode and Equals for object reference?

我有一个小众的需求,需要锁定两个通用类型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?
        }
    }

}

采用

System.identityHashCode

==

您可以使用==来检查内存标识,并可以使用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;
    }
}

==运算符不应该断言引用相等吗?

这个问题可能会解决您对hashCode的关注: 当toString()和hashCode()被覆盖时,如何获取Java对象的“对象引用”? (在下面引用)

您打算如何计划使用它(您想做什么与需要调用的内容有所不同)?

在Javadocs中定义的hashCode()表示:

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

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

System.identityHashCode执行以下操作:

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

对于您正在执行的操作,听起来听起来像您想要的...但是根据库的实现方式,您想要执行的操作可能并不安全。

您应该将其用于hashCode:

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

并且等于:

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

基本上转嫁责任。

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

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

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

如果您有一个超类,则处理超类的前3个步骤将被视为一种好样式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM