2

すでにシリアル化されたデータ、つまりキーと値の両方がバイト配列であるヘーゼルキャストマルチマップとマップを使用しようとしています。以下に示すように、期待どおりに機能しません。

javadocでは、「gotchas」セクションで、ハッシュはシリアル化された形式のhazelcastによって処理され、hashCodeおよびequals(バイト配列の場合はオーバーライドされません)の実装に依存しないことに注意してください。ですから、どうやらObject.hashcodeが使われているのかわかりません。

バイト配列でヘーゼルキャストマップを使用する方法を誰かに教えてもらえますか?

適切にオーバーライドされたハッシュコード/等しいメソッドを使用してバイト配列ラッパーを格納する義務がありますか?

助けてくれてありがとう。

問題:

 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)
4

1 に答える 1

1

私はここで私自身の質問に答えます。なぜなら、ヘーゼルキャストのドキュメントでは、次のように明確に述べられていないと思うからです。

  • キーオブジェクトは、equals/hashcodeをオーバーライドする必要はありません
  • 値オブジェクトは、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とハッシュコードをオーバーライドするラッパーが必要です。残念ながら、valueクラス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)
}
于 2013-03-06T11:01:13.743 に答える