【问题标题】:object reference set in javajava中的对象引用集
【发布时间】:2010-04-29 14:43:11
【问题描述】:

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

我不确定如何在 Java 中执行此操作。

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

【问题讨论】:

    标签: java collections


    【解决方案1】:

    我猜java.util.IdentityHashMap 是您正在寻找的(注意,没有IdentityHashSet)。查找 API 文档:

    该类使用哈希表实现Map 接口,在比较键(和值)时使用引用相等代替对象相等。换句话说,在IdentityHashMap 中,两个键k1k2 被认为是相等的当且仅当(k1==k2)。 (在正常的Map 实现中(如HashMap)两个键k1k2 被认为是相等的当且仅当(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
    • +1 - 基于 Map 实现的 Set 应该很容易实现。这就是 HashSet 的实现方式...
    • 在 JDK 中甚至有一种方法可以创建一个带有指定支持 MapSet,它被称为 newSetFromMapjava.sun.com/javase/6/docs/api/java/util/…
    • @Carl:您可以查看java.util.HashSet 的源代码(可以在JDK 安装目录的src.zip 文件中找到),您将看到它在幕后使用了HashMap(正如斯蒂芬C所说,它是根据HashMap实现的)。
    【解决方案2】:

    您可以将您的对象包装到一个包装器类中,然后该包装器类可以根据对象的身份实现hashcodeequals

    【讨论】:

    • +1 - 这在他无法修复方法的情况下是可行的,并且扩展现有类不是一种选择。
    • 如果您懒得编写自己的包装类,只需使用 1 元素 Object[]。丑陋,但有效。
    • @polygenelubricants:聪明!这是我没有想到的。
    • @Carl:刚刚发现了一些可能更好的东西:java.sun.com/javase/6/docs/api/java/util/concurrent/atomic/…
    • @polygenelubricants:我在跟踪你时遇到了一些麻烦。据我了解,AtomicReferences 有一个截然不同的目的。是的,它们会包装,但我怀疑它们包含各种不相关的管道来执行它们的并发驯服魔法。不过我没仔细看。
    【解决方案3】:

    您可以扩展 HashSet(或实际上 - AbstractSet),并使用 IdentityHashMap 支持它,它使用 System.identityHashCode(object) 而不是 obj.hashCode()

    你可以简单地用谷歌搜索IdentityHashSet,已经有一些实现了。或者按照 Joachim Sauer 的建议使用 Collections.newSetFromMap(..)

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

    【讨论】:

    • 似乎覆盖hashCode() 比扩展HashSet 更容易。
    • 如果对象不在他的“财产”中
    • 对 - 听起来像是,但我可能弄错了。
    • 对象是 Hibernate 实体 bean。无法正确实现这些功能,因为这样做 1. 需要一个打开的休眠会话,并且 2. 可能会遍历整个数据库!
    • 不休眠实体bean通常包含主键吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    相关资源
    最近更新 更多