Range方法返回对象转换办法

在上篇中发现了一个问题,明明存的是一个对象的集合,为什么通过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解释参考:JSON 字符串是如何被解析的?JsonParser 了解一下_Java技术那些事儿的博客-CSDN博客_json parser

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

以上就是为何返回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)

运行测试:

 可以发现转换成功了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扶朕去网吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值