2012-09-17 28 views
2

我試圖使用hazelcast multimaps和映射與已經序列化的數據,即鍵和值都是字節數組。如下所示,它不能按預期工作。哈希問題。如何使用帶有字節數組鍵和值的hazelcast map/multimap?

在javadoc中,在「gotchas」部分中指出哈希是通過序列化表單上的hazelcast處理的,並且不依賴於hashCode和equals(它們在字節數組情況下不會被重寫)的實現。所以,我不明白爲什麼顯然,使用Object.hashcode。

請有人告訴我如何使用帶有字節數組的榛木地圖?

我是否有義務用足夠重寫的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

我在這裏回答我的問題,因爲我覺得hazelcast文檔中沒有明確規定,因爲它可以:

  • 關鍵OBJETS不需要重寫equals /哈希碼
  • 值OBJETS需要重載equals /哈希碼

釷是可以通過這個簡單的測試可以看出:

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的類,所以我們不能避免使用boxing :-(

此外,如果你想用order來索引,wrapper必須是一個可比較的。

這裏是一個明智的實現這樣一個包裝的:

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) 
} 
相關問題