java中的对象引用集
我需要创建一组对象。问题是我不想将散列或等式建立在对象的hashCode和equals实现的基础上。相反,我希望哈希代码和等式仅基于每个对象的引用标识(即:引用指针的值) 我不知道如何在Java中做到这一点java中的对象引用集,java,collections,Java,Collections,我需要创建一组对象。问题是我不想将散列或等式建立在对象的hashCode和equals实现的基础上。相反,我希望哈希代码和等式仅基于每个对象的引用标识(即:引用指针的值) 我不知道如何在Java中做到这一点 这背后的原因是我的对象不能可靠地实现equals或hashCode,在这种情况下,引用标识就足够了。您可以扩展HashSet(或者实际上是-AbstractSet),并使用它来代替obj.hashCode() 您只需在谷歌上搜索IdentityHashSet,已有一些实现。或者使用Joach
这背后的原因是我的对象不能可靠地实现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:我跟不上你。据我所知,原子引用有着截然不同的目的。是的,它们是包装的,但我怀疑它们包含各种不相关的管道来实现并发控制的魔力。不过,我没有仔细看。