2015-08-08 196 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