【发布时间】:2010-04-29 14:43:11
【问题描述】:
我需要创建一组对象。问题是我不想将散列或相等基于对象的 hashCode 和 equals 实现。相反,我希望哈希码和相等性仅基于每个对象的引用标识(即:引用指针的值)。
我不确定如何在 Java 中执行此操作。
这背后的原因是我的对象没有可靠地实现equals或hashCode,在这种情况下引用标识就足够了。
【问题讨论】:
标签: java collections
我需要创建一组对象。问题是我不想将散列或相等基于对象的 hashCode 和 equals 实现。相反,我希望哈希码和相等性仅基于每个对象的引用标识(即:引用指针的值)。
我不确定如何在 Java 中执行此操作。
这背后的原因是我的对象没有可靠地实现equals或hashCode,在这种情况下引用标识就足够了。
【问题讨论】:
标签: java collections
我猜java.util.IdentityHashMap 是您正在寻找的(注意,没有IdentityHashSet)。查找 API 文档:
该类使用哈希表实现
Map接口,在比较键(和值)时使用引用相等代替对象相等。换句话说,在IdentityHashMap中,两个键k1和k2被认为是相等的当且仅当(k1==k2)。 (在正常的Map实现中(如HashMap)两个键k1和k2被认为是相等的当且仅当(k1==null ? k2==null : k1.equals(k2))。)这个类不是通用的
Map实现!虽然这个类实现了Map接口,但它故意违反了Map的一般合同,该合同要求在比较对象时使用equals方法。此类仅在需要引用相等语义的极少数情况下使用。
编辑:见下方 Joachim Sauer 的评论,基于某个 Map 制作 Set 真的很容易。你需要做这样的事情:
Set<E> mySet = Collections.newSetFromMap(new IdentityHashMap<E, Boolean>());
【讨论】:
Map 接口与Set 接口的用法完全不同。
Set。
Map 的 Set,它被称为 newSetFromMap:java.sun.com/javase/6/docs/api/java/util/…
java.util.HashSet 的源代码(可以在JDK 安装目录的src.zip 文件中找到),您将看到它在幕后使用了HashMap(正如斯蒂芬C所说,它是根据HashMap实现的)。
您可以将您的对象包装到一个包装器类中,然后该包装器类可以根据对象的身份实现hashcode 和equals。
【讨论】:
Object[]。丑陋,但有效。
您可以扩展 HashSet(或实际上 - AbstractSet),并使用 IdentityHashMap 支持它,它使用 System.identityHashCode(object) 而不是 obj.hashCode()。
你可以简单地用谷歌搜索IdentityHashSet,已经有一些实现了。或者按照 Joachim Sauer 的建议使用 Collections.newSetFromMap(..)。
这当然应该只在你不“拥有”你的对象类时才应该这样做。否则只需修复他们的hashCode()
【讨论】:
hashCode() 比扩展HashSet 更容易。