【问题标题】:How to get a correct array hashcode in scala?如何在scala中获得正确的数组哈希码?
【发布时间】:2016-11-18 13:59:43
【问题描述】:

根据其内容计算 Array 的 hashCode 的合适方法是什么?

Array.hashCode 用于数组实例:

val h = a.hashCode
println(h == Array(1,2).hashCode) // false

a(0) = 42
println(h == a.hashCode) // true

注意:在计算 hashCode 之前最好避免将整个数组复制到列表中

为什么问:我在类中使用数组(作为私有字段),因为查找时间很关键,并且它的内容与计算类的 hashCode 相关

【问题讨论】:

    标签: arrays scala hashcode


    【解决方案1】:

    来自https://issues.scala-lang.org/browse/SI-1607,它说Array的hashCode是java的hashCode,因为scala Array是java Array。斯卡拉无法改变它。

    但它也说scala在WrappedArray中有一个合适的hashCode方法。 因此:

    val a = Array(1,2)
    val h = a.toSeq.hashCode // wrapped it in a WrappedArray - no copy
    println(h == Array(1,2).toSeq.hashCode) // true
    
    a(0) = 42
    println(h == a.toSeq.hashCode) // false
    

    【讨论】:

      【解决方案2】:

      您也可以使用java.util.Arrays.hashCode(a),它可能比a.toSeq.hashCode 更快(因为WrappedArray 似乎继承了非数组特定的实现)。

      【讨论】:

      • 它适用于 Array[Int] 但我不知道它如何适用于其他(通用)项目类型。我想我们需要在更一般的情况下将项目转换为对象,或者使用其他一些 java 函数(?)。最后,我更喜欢依赖 scala API。但可能有一些我不知道的缺点(效率?)。
      • WrappedArray 可能有一点开销:它需要一个简单的类构造(包装数组)并且每次查找都需要一个额外的函数调用。但根据我的经验,很难看出直接查找的区别。我试过了,没有管理
      • 我已经提出了一个拉取请求以确保这不再是一个问题,并且它已被批准github.com/scala/scala/pull/5551
      【解决方案3】:

      您可以直接使用MurmurHash3算法。

      import scala.util.hashing.MurmurHash3
      
      MurmurHash3.orderedHash(Array(1,2)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-29
        • 1970-01-01
        • 2010-12-09
        • 2012-07-28
        • 1970-01-01
        • 1970-01-01
        • 2019-05-25
        • 1970-01-01
        相关资源
        最近更新 更多