2015-08-08 133 views
0

Got started looking at Hazelcast(3.4.4)。最小配置。測試:Hazelcast總是返回null,containsKey總是返回false

case class Ticket(id:Int, name:String) 

val ticketCount = 20 
     val tickets:List[Ticket] = for { n <- (0 until ticketCount).toList } yield Ticket(n, s"ticket$n") 

val map: IMap[Long, Ticket] = hz1.getMap[Long,Ticket]("com.foo.testmap") 

tickets foreach { t => 
    println(s"submitting $t") 
    Thread.sleep(10) // some delay to submit one ticket 
    map.putIfAbsent(t.id, t) 
} 


Thread.sleep(2000) // two seconds to make sure all is set.. 


var value1 = map.get(19)    // null 

var value2 = map.containsKey(19)) // false 

val value3 = map.getAsync(19).get() // Ticket(19,ticket19) 

爲什麼null,爲什麼false,爲什麼只有map.getAsync(19).get()作品?

這一點,雖然:

val iterator = map.entrySet().iterator()  // will print all values 
    while(iterator.hasNext) { 
    val next = iterator.next() 
    println(next) 
    } 

將打印的所有條目。

更新:

在配置:

<map name="com.foo.testmap"> 
    <in-memory-format>OBJECT</in-memory-format> 
</map> 

回答

4

它的工作原理是,當你改變var value1 = map.get(19)var value1 = map.get(19l)

將數據存儲到地圖時,您使用的是長爲鍵預期。但是,您正在使用Integer來獲取數據。正如您在IMap contract中看到的那樣,相等比較使用密鑰的二進制(序列化)形式,而不是密鑰本身。很明顯,一個long被序列化爲一個不同於整數的二進制數。

getAsync()的工作原理與get()方法不同,它使用泛型,我假定Scala編譯器將密鑰轉換爲場景後面的Long。

這是自動裝箱和Scala編譯器巫術的結合,創造了看似不一致的行爲。然而,當我想到它時,並不是那麼出乎意料。 j.u.Map的行爲完全相同。以下測試失敗以及:

@Test 
public void surpriseNotReally() { 
    Map<Long, String> map = new HashMap<>(); 

    long key = 1; 
    String expectedValue = "foo"; 
    map.put(key, expectedValue); 

    String actualValue = map.get(1); 
    assertEquals(expectedValue, actualValue); 
} 
+0

好趕上..謝謝。 – ses