上一篇:关于Redis的问题探讨(一):为何存放集合偏向于转String后存放而非直接存

在上篇中发现了一个问题,明明存的是一个对象的集合,为什么通过range方法返回的却是LinkeHashMap

于是通过debug看看源码,了解执行流程,找一下原因

这是笔者通过debug画出的大致流程:

注意看8中,mapObject方法,这里就是返回LinkeHashMap的原因,这里重点解析一下mapObject方法:

protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOException {
       // 获取字段名称,也就是key
String key1 = p.getText();
       // 执行前该token是FIELD_NAME,也就是字段名称
       // 然后执行nextToken()后,变为了VALUE_STRING,也就是String类型的字段值
       // 但是如果值不为String类型,那就会在后面又执行一次nextToken,变为VALUE_NUMBER_INT,也就是整数型字段值
p.nextToken();
Object value1 = this.deserialize(p, ctxt);
String key2 = p.nextFieldName();
if (key2 == null) {
LinkedHashMap<String, Object> result = new LinkedHashMap(2);
result.put(key1, value1);
return result;
} else {
          // 解释在上面
p.nextToken();
          // 获取value值
Object value2 = this.deserialize(p, ctxt);
String key = p.nextFieldName();
LinkedHashMap result;
if (key == null) {
result = new LinkedHashMap(4);
result.put(key1, value1);
result.put(key2, value2);
return result;
} else {
result = new LinkedHashMap();
result.put(key1, value1);
result.put(key2, value2); do {
p.nextToken();
result.put(key, this.deserialize(p, ctxt));
} while((key = p.nextFieldName()) != null); return result;
}
}
}

首先就是这个p也就是JsonParser对象,他是通过JsonFactory的createParser方法创建的,其作用是解析Json字符串,因此在执行之前mapObject之前就已经将value解析并存入JsonParser中了。

JsonParser解释参考:https://blog.csdn.net/LBWNB_Java/article/details/120003565

然后执行流程可以参考注释

以上就是为何返回LinkeHashMap的原因,那么如何解决呢

这里就要用到ObjectMapper,在range方法的流程图中也看到其实也使用了他

通过ObjectMapper的convertValue方法将LinkeHashMap转为目标对象:

@Test
public void testRange() {
String key = "right_push_all_01";
List<LinkedHashMap<String, Object>> linkedHashMapList = redisService.lRange(key, 0, -1);
ObjectMapper objectMapper = new ObjectMapper();
List<ThisIsDTO> thisIsDTOList = objectMapper.convertValue(linkedHashMapList, new TypeReference<List<ThisIsDTO>>() {
});
for (ThisIsDTO thisIsDTO : thisIsDTOList) {
System.out.println(thisIsDTO.getAge());
}
}

注意:因为是集合存放,所以一定要new TypeReference<List<ThisIsDTO>>来定义转换的类型

如果只是单个对象,可以直接 objectMapper.convertValue(linkedHashMap, ThisIsDTO.class)

运行测试:

可以发现转换成功了

关于Redis的问题探讨(二):Range方法返回的对象是LinkeHashMap以及转换办法的更多相关文章

  1. Python/dotNET Redis服务连接客户端调用SET方法的同时获取Redis服务器返回的内容

    在用Python或dotNET redis客户端连接redis服务器的时候,当你调用客户端的SET方法后同时还想得到其返回的字符串,那么需要处理一下. 1. Redis Python redis客户端 ...

  2. Java 使用Redis缓存工具的图文详细方法

    开始在 Java 中使用 Redis 前, 我们需要确保已经安装了 redis 服务及 Java redis 驱动,且你的机器上能正常使用 Java. (1)Java的安装配置可以参考我们的 Java ...

  3. Redis学习笔记(二)-key相关命令【转载】

    转自 Redis学习笔记(二)-key相关命令 - 点解 - 博客园http://www.cnblogs.com/leny/p/5638764.html Redis支持的各种数据类型包括string, ...

  4. Go 语言入门(二)方法和接口

    写在前面 在学习 Go 语言之前,我自己是有一定的 Java 和 C++ 基础的,这篇文章主要是基于A tour of Go编写的,主要是希望记录一下自己的学习历程,加深自己的理解 Go 语言入门(二 ...

  5. Redis详解(二)——AOF

    Redis详解(二)--AOF 前言 RDB 持久化存在一个缺点是一定时间内做一次备份,如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失).对于数据完整性要求很严格的需求 ...

  6. Redis性能篇(二)CPU核和NUMA架构的影响

    Redis被广泛使用的一个很重要的原因是它的高性能.因此我们必要要重视所有可能影响Redis性能的因素.机制以及应对方案.影响Redis性能的五大方面的潜在因素,分别是: Redis内部的阻塞式操作 ...

  7. mysql 远程连接数据库的二种方法

    http://blog.csdn.net/freecodetor/article/details/5799550 一.连接远程数据库: 1.显示密码 如:MySQL 连接远程数据库(192.168.5 ...

  8. IIS7.5使用web.config设置伪静态的二种方法

    转自 网上赚钱自学网 .http://www.whosmall.com/post/121 近几天公司里开发的项目有几个运行在IIS7.5上,由于全站采用的是伪静态,因此从网上找到两两种方法来实现.这两 ...

  9. Redis实战之征服 Redis + Jedis + Spring (二)

    不得不说,用哈希操作来存对象,有点自讨苦吃! 不过,既然吃了苦,也做个记录,也许以后API升级后,能好用些呢?! 或许,是我的理解不对,没有真正的理解哈希表. 相关链接: Redis实战 Redis实 ...

随机推荐

  1. 翻译:HTML5与HTML4的区别

    本文选译自:W3C Working Group Note: HTML5 Differences from HTML4. 解释一下W3C Working Group Note,作为"工作组笔记 ...

  2. mysql实现in子句的limit查询 (转)

    在supesite里面执行一个SQL语句: select * from supe_spaceitems where catid=98 and itemid not in(select itemid f ...

  3. Muse UI遇到的坑

    写在前面:我只是一个前端小白,文章中的提到可能会有不足之处,仅提供一个参考.若有不完善的地方,欢迎各位大佬指出,希望对你有帮助! 故事背景是这样的,最近做一个Vue项目,使用到 Muse UI 组件库 ...

  4. C# 委托专题

    单播委托:一个委托只指向一个方法: 多播委托:一个委托指向多个方法,形成一个方法链: Main是静态方法,里面只能引用静态方法,而不能引用实例方法: Main可以进行类的实例化,然后引用实例化后的方法 ...

  5. java中线程有什么用?

    线程有什么用? 通过引入线程技术,在浏览器中你可以浏览网页的同时,播放动画和声音效果,同时在后台打印一个页面.例如老板可以同时处理工程师,秘书和清洁人员的事,这 就是多线程处理机制.Within th ...

  6. java中如何使用接口继承(Extending Interfaces)

    5.接口继承(Extending Interfaces)和通话talk的功能.而Moto888更为高级,除了照相和通话功能以外,还有mp3的功能.接口继承到底有什么意义呢?马克-to-win:1)通过 ...

  7. 使用element UI el-upload组件实现视频文件上传及上传进度显示方法总结

    实现效果: 上传中: 上传完成: 代码: <el-form-item label="视频上传" prop="Video"> <!-- acti ...

  8. python 简要小结

    初学python 简单总结部分内置函数 将两个数组合并为元组:zip()   解压:zip(*zip) range(a,b,c) 取值范围 起始:a   结尾:b   间隔:c   (参数不能为空否则 ...

  9. 异步任务-springboot

    异步任务-springboot 异步:异步与同步相对,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作.也就是说无论异步方法执行代码需要多长时间,跟主线程没有任何影响,主线程 ...

  10. 1.Markdown语法

    Markdown学习 一.标题:(# +标题名字) 标题 三级标题 四级标题 二.字体 (空格内容前后的空格删掉) Hello,World! **粗体** Hello,World! *斜体* Hell ...