java中的对象引用集

java中的对象引用集,java,collections,Java,Collections,我需要创建一组对象。问题是我不想将散列或等式建立在对象的hashCode和equals实现的基础上。相反,我希望哈希代码和等式仅基于每个对象的引用标识(即:引用指针的值) 我不知道如何在Java中做到这一点 这背后的原因是我的对象不能可靠地实现equals或hashCode,在这种情况下,引用标识就足够了。您可以扩展HashSet(或者实际上是-AbstractSet),并使用它来代替obj.hashCode() 您只需在谷歌上搜索IdentityHashSet,已有一些实现。或者使用Joach

我需要创建一组对象。问题是我不想将散列或等式建立在对象的hashCode和equals实现的基础上。相反,我希望哈希代码和等式仅基于每个对象的引用标识(即:引用指针的值)

我不知道如何在Java中做到这一点


这背后的原因是我的对象不能可靠地实现equals或hashCode,在这种情况下,引用标识就足够了。

您可以扩展
HashSet
(或者实际上是-
AbstractSet
),并使用它来代替
obj.hashCode()

您只需在谷歌上搜索
IdentityHashSet
,已有一些实现。或者使用Joachim Sauer建议的
Collections.newSetFromMap(..)

当然,只有当您不“拥有”对象的类时,才应该这样做。否则,只需修复它们的
hashCode()

我想这就是您要查找的内容(注意,没有
IdentityHashSet
)。查阅API文档:

此类使用哈希表实现
Map
接口,在比较键(和值)时使用引用相等代替对象相等。换句话说,在
标识hashmap
中,当且仅当
(k1==k2)
时,两个键
k1
k2
被视为相等。(在正常的
Map
实现中(如
HashMap
),当且仅当
(k1==null?k2==null:k1.equals(k2))时,两个键
k1
k2
被视为相等)

此类不是通用的
Map
实现!虽然此类实现了
Map
接口,但它故意违反了
Map
的一般约定,该约定要求在比较对象时使用
equals
方法。此类仅设计用于少数需要引用相等语义的情况

编辑:参见下面的Joachim Sauer评论,根据某个
地图
制作
集合
非常容易。您需要这样做:

Set<E> mySet = Collections.newSetFromMap(new IdentityHashMap<E, Boolean>());
Set mySet=Collections.newSetFromMap(newidentityhashmap());

您可以将对象包装到一个包装类中,然后该类可以简单地基于对象的标识实现
hashcode
equals

除了
映射
接口的用法与
接口完全不同之外。实际上,集只是一个忽略值的映射。如果您不想在应用程序中一直处理它,您可以很容易地编写一个包装器,使它看起来更像一个
集合。+1-基于映射实现实现集合应该很容易。这就是HashSet的实现方式……JDK中甚至有一种方法可以创建一个具有指定支持的
,它被称为
newSetFromMap
:@Carl:您可以查看
java.util.HashSet
的源代码(可以在JDK安装目录中的src.zip文件中找到)你会看到它在封面下使用了一个
HashMap
(正如Stephen C所说,它是按照
HashMap
实现的)。似乎覆盖
hashCode()
要比扩展
HashSet
容易得多。如果对象不是他“拥有的”对-听起来像是,但我可能弄错了。对象是Hibernate实体bean。不可能正确实现这些功能,因为这样做需要1。需要一个打开的hibernate会话,以及2。将可能遍历整个数据库!hibernate实体bean通常不包含主键吗?+1-这在他无法修复方法的情况下是可行的,扩展现有类不是一个选项。如果你太懒了,无法编写自己的包装类,只需使用一个1元素的
对象[]
。丑陋,但有效。@Polygene:聪明!我没想到。@Carl:刚刚找到了更好的办法:@Polygene:我跟不上你。据我所知,原子引用有着截然不同的目的。是的,它们是包装的,但我怀疑它们包含各种不相关的管道来实现并发控制的魔力。不过,我没有仔细看。