【问题标题】:Can I create a collection in Scala that uses different equals/hashCode/compare implementations?我可以在 Scala 中创建一个使用不同 equals/hashCode/compare 实现的集合吗?
【发布时间】:2011-02-09 08:38:30
【问题描述】:

我正在寻找创建身份集的简单方法。我只是希望能够在遍历图表时跟踪我是否“看到”了特定对象。

我不能使用常规 Set,因为 Set 使用“==”(Scala 中的 equals 方法)来比较元素。我想要的是一个使用“eq”的集合。

有没有什么方法可以在 Scala 中创建一个使用某些应用程序指定的方法来测试相等性而不是在集合元素上调用 equals 的 Set?我寻找了某种可以覆盖但没有找到的“wrapEquals”方法。

我知道我可以使用 Java 的 IdentityHashMap,但我正在寻找更通用的东西。

我的另一个想法是将每个 set 元素包装在另一个根据 eq 实现 equals 的对象中,但是为了获得新的 equals 实现而生成大量新对象是浪费的。

谢谢!

【问题讨论】:

    标签: scala scala-collections


    【解决方案1】:

    根据您的需要,您可以创建一个框,对包含的元素使用身份检查,例如:

    class IdentBox[T <: AnyRef](val value: T) {
    
        override def equals(other: Any): Boolean = other match {
          case that: IdentBox[T] => that.value eq this.value
          case _ => false
        }
    
        override def hashCode(): Int = value.hashCode
    
      }
    

    并使集合包含那些框而不是直接包含元素:Set[IdentBox[T]]

    它有一些装箱/拆箱的开销,但在您的用例中可能是可以容忍的。

    【讨论】:

    • 您提供的hashCode 有效(实际上任何哈希都可以工作,只要它为同一实例返回相同的值),但也许System.identityHashCode(value) 会更好?
    • 鉴于 Willis Blackburn 在此问题的另一个答案中的评论,我不确定这一点:不幸的是 System.identityHashCode 返回默认哈希码值,而不是地址,因此两个不同的对象可以具有相同的 identityHashCode价值。
    • identityHashCode 是一个 32b 位值 (int),因此不能(也不能)保证它在 64b JVM 上是唯一的。尽管如此,它很可能比hashValue 更独特,hashValue 旨在与您现在使用的case class 价值平等合作。在您的情况下,任何事情都有效,因为您不会使用 identityHashCode 进行比较,而只是作为散列来伴随基于 eq 的比较。
    【解决方案2】:

    This 是一个类似的问题。在这种情况下,接受的答案是使用TreeSet 并提供自定义Comparator

    【讨论】:

      【解决方案3】:

      由于您不需要对“已见”对象的引用,而只需要“包含”的布尔值,我建议只使用 mutable.Set[Int] 并使用通过调用 System.identityHashCode(obj) 获得的值加载它。

      Scala 自定义集合具有足够的概念表面积,足以吓跑大多数想要像这样快速调整的人。

      【讨论】:

      • 不幸的是 System.identityHashCode 返回默认的哈希码值,而不是地址,所以两个不同的对象可以有相同的 identityHashCode 值。它可能在 32 位 JVM 中工作,但在 64 位 JVM 中,肯定会有一些冲突。
      • 如果您希望您的软件每次都能正常工作,这只是个问题。 :-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 2014-10-12
      相关资源
      最近更新 更多