一、概述
起初是要把数据存储到redis,在RedisTemplate和StringRedisTemplate中纠结。顾名思义StringRedisTemplate操作字符串类型的数据,RedisTemplate可存储的数据类型较多,但是操作也较为复杂。又鉴于,我是在完善别人的系统,所以延用了原来的开发者使用的StringRedisTemplate。
那么我在存储Map<Long,String>类型数据的时候,就要先将其转化成JSON字符串再存起来(使用的是fastjson)。可是这样导致一个问题,就是取数据的时候,得到的是JSON字符串,该如何还原为原来的Map<Long,Stirng>类型?
二、问题探索
为了解决这个问题,经历了以下过程:
- 原来很直接的,第一个做法当然是简单粗暴地强制类型转化,先转成JSONObject,再强制转Map
但是失败了,会报Unchecked cast错误。 - 百度如何解决这个错误,很多博客告诉我,设置@SuppressWarnings(“unchecked”),这样就不会报错了。要知道这样根本没解决问题,只是选择忽略错误让它不提示。
- 搜索到一篇相关文章,虽然不是转化成map,但也给了我启发和方向。
- 依葫芦画瓢,将文章中的转化函数改成map,失败了,根本不能这样套用
public static <T,K> Map<T,K> castMap(Object obj, Class<T> clazz1,Class<T> clazz2)
{
Map<T,K> result = new HashMap<>();
if(obj instanceof Map<?,?>)
{
for (Object key : ((Map<?,?>) obj).Keyset())
{
result.put(clazz1.cast(key),clazz2.cast(((Map<T,K>) obj).get(key)));//这里转化失败了
}
return result;
}
return null;
}
- 于是又退一步,想查找fastjson有没有现成的方法。得知可以转化成map,但key和value的类型不能指定(也可能是我不会🤪),导致原来我要得到Long却会有部分转化成Integer的情况。好吧,那有没有办法把Integer转化成Long呢? 强转的话还是老问题报Unchecked cast错误,因为Integer和Long没有任何继承关系无法转化。
- 最后是怎么解决的呢。有意思的是,问题出在JSON上,解决问题也是靠它。既然Integer没法直接转Long,那我可以通过JSON间接转。也就是Integer转JSONString,JSONString转Long,成功解决。
三、代码实现
以下的User为自定义类型,同样可以转化
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
HashMap<Long,User> map=new HashMap<Long, User>();
map.put(new Long("1234564688888888884"),new User("Li",1));
map.put(new Long("151561615"),new User("Huang",2));
//如果直接转Map,上面这个长度的key就会自动转为Integer,
//用一个值和这个key一样但类型为Long的数据作为参数,
//是无法get相应的value的,取得的是null
String mapJSONString= JSONObject.toJSONString(map);
Object mapObject=JSON.parse(mapJSONString);
HashMap resultMap=castMap(mapObject,Long.class,User.class);
System.out.println(resultMap.get(new Long("1234564688888888884")).toString());
System.out.println(resultMap.get(new Long("151561615")).toString());
}
private static <T, K> HashMap<T,K> castMap(Object obj, Class<T> clazz1, Class<K> clazz2)
{
HashMap<T,K> result=new HashMap<>();
if(obj instanceof Map<?,?>) {
for (Object key : ((Map<?,?>) obj).keySet()) {
T newkey=JSON.parseObject(JSON.toJSONString(key), clazz1);
Object value=((Map<?,?>) obj).get(key);
K newValue=JSON.parseObject(JSON.toJSONString(value), clazz2);
result.put(newkey,newValue);
}
return result;
}
return null;
}
}