背景
将一個類型為Map<Integer, String>的一個Map對象放到redis中後,再次取出來時。當我們想便利Map.entrySet()擷取每個Entry中的Key,如執行Integer key = entry.getKey();
那麼在執行時就會報錯:java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
Map<Integer,String> cacheMap =(Map<Integer,String>)redisCache.get(key);
for (Map.Entry<Integer, String> entry : cacheMap.entrySet()) {
Integer key = entry.getKey();
String value = entry.getValue();
}
探究
debug時發現,在從redis獲得這個Map<Integer,String> cacheMap對象時,它其中的Key的實際類型已經是String類型。這是因為redisson采用JsonJacksonCodec反序列化時,是用Object作為對象decode。在這一步會預設把key設定成string。
private final Decoder<Object> decoder = new Decoder<Object>() {
@Override
public Object decode(ByteBuf buf, State state) throws IOException {
return mapObjectMapper.readValue((InputStream) new ByteBufInputStream(buf), Object.class);
}
};
測試
@Test
public void testMap() throws IOException {
ObjectMapper mapper = new ObjectMapper();
HashMap<Integer, String> map = new HashMap<>();
map.put(11, "little");
map.put(6, "nuts");
String s = mapper.writeValueAsString(map);
//{"11":"little","6":"nuts"}
System.out.println(s);
HashMap o = (HashMap)mapper.readValue(s, Object.class);
assertEquals(o.get("11"), "little");
assertNotEquals(o.get(11), "little");
}
總結
如果要針對,對象進行JsonJackson序列化時,如果對象是Map,則需要注意不要用Integer做為key。如果要将一個json對象作為redis緩存時,同樣不要将Integer當作HashMap的key類型。
本篇文章如有幫助到您,請給「翎野君」點個贊,感謝您的支援。
作者:翎野君
如果您喜歡或希望看到更多我的文章,可掃描二維碼關注我的微信公衆号《翎野君》。