哈希问题。如何使用带字节数组键和值的hazelcast map / multimap?

时间:2012-09-17 13:53:41

标签: scala hash hazelcast

我正在尝试使用hazelcast multimaps和已经序列化数据的映射,即键和值都是字节数组。如下所示,它不能按预期工作。

在javadoc中,在“gotchas”部分中注意到散列是由序列化表单上的hazelcast处理的,并且不依赖于hashCode和equals的实现(在字节数组的情况下不会覆盖)。所以,我不明白为什么显然使用Object.hashcode。

请问有人告诉我如何使用带字节数组的hazelcast映射?

我是否有义务使用充分覆盖的hashcode / equal方法存储字节数组包装器?

感谢您的帮助。

问题:

 scala> val mm:MultiMap[Array[Byte], Array[Byte]] = hi.getMultiMap("test-baMuMa")
 mm: com.hazelcast.core.MultiMap[Array[Byte],Array[Byte]] = MultiMap [test-baMuMa]

 scala> mm.put("a".getBytes,"b".getBytes)
 res29: Boolean = true

 scala> mm.put("a".getBytes,"b".getBytes)
 res30: Boolean = true
 // => should return false..

 scala> mm.remove("a".getBytes,"b".getBytes)
 res31: Boolean = false
 // =>  should return true

 scala> mm.containsEntry("a".getBytes,"b".getBytes)
 res32: Boolean = false
 // =>  should return true (confirmed that removal did not occur)

1 个答案:

答案 0 :(得分:1)

我在这里回答我自己的问题,因为我认为在淡褐色文档中没有尽可能清楚地说明:

  • key objets不需要覆盖equals / hashcode
  • value objets需要覆盖equals / hashcode

这可以通过这个简单的测试看出:

object TestHazel{

  class Klaus(a:Int) extends Serializable
  // class does not override equals/hashcode

  def main (args:Array[Byte]){
    import com.hazelcast.core._
    val hi = Hazelcast.newHazelcastInstance
    val map = hi.getMap[Klaus, Klaus]("asdf")
    val klaus1 = new Klaus(1)
    map.put(klaus1, klaus1)
    val containsKey = map.containsKey(new Klaus(1))
    println("\n\ncheck if key overrides equals/hashcode: " + containsKey)
    // true

    val containsValue = map.containsValue(new Klaus(1))
    println("\n\ncheck if value overrides equals/hashcode: " + containsValue + "\n\n")
    // false

    hi.shutdown
 }
}

因此,就我而言,对于字节数组值,需要一个覆盖equals和hashcode的包装器。不幸的是,值类scala> = 2.10不能用于重写equals / hashcode的类,所以我们无法避免拳击:-(

此外,如果您想使用订单进行索引,则包装器必须是可比较的。

这是一个合理的实现这样的包装器:

class BAWrapper2(ba:Array[Byte], comparator:Comparator[Array[Byte]]) 
    extends Serializable with Comparable[BAWrapper2] 
{
  def data: Array[Byte] = if (ba == null) Array.empty[Byte] else ba
  def equals(other:BAWrapper2):Boolean = util.Arrays.equals(data, other.data)
  override def equals(obj:Any):Boolean = 
    if (obj.isInstanceOf[BAWrapper2]) equals(obj.asInstanceOf[BAWrapper2]) 
    else false
  override def compareTo(that:BAWrapper2):Int =
    if (comparator != null) comparator.compare(this.data, that.data)
    else BAComparator.compare(this.data, that.data)
  override def hashCode:Int = util.Arrays.hashCode(data)
}