长字符串转实体类

实际字符串

        String dataStr = "{\n" +
                "  \"data\": [\n" +
                "    {\n" +
                "      \"data\": [\n" +
                "        {\n" +
                "          \"areaId\": 1,\n" +
                "          \"H\": 2,\n" +
                "          \"S\": 3,\n" +
                "          \"Q\": 12\n" +
                "        },\n" +
                "        {\n" +
                "          \"H\": 1,\n" +
                "          \"S\": 3,\n" +
                "          \"Q\": 12,\n" +
                "          \"areaId\": 2\n" +
                "        }\n" +
                "      ],\n" +
                "      \"time\": \"2024-01-01 00:00:00\"\n" +
                "    },{\t  \"data\": [\n" +
                "        {\n" +
                "          \"areaId\": 1,\n" +
                "          \"H\": 122,\n" +
                "          \"S\": 3,\n" +
                "          \"Q\": 121\n" +
                "        },\n" +
                "        {\n" +
                "          \"H\": 121,\n" +
                "          \"S\": 3,\n" +
                "          \"Q\": 122,\n" +
                "          \"areaId\": 2\n" +
                "        }\n" +
                "      ],\n" +
                "      \"time\": \"2024-01-01 02:00:00\"}\n" +
                "  ],\n" +
                "  \"state\": true\n" +
                "}";

实际使用过程中这个dataStr.length()长度达到了1.5亿左右,转换成一份txt文档,140+M,note打不开了,网上json格式化工具也格式化不了,测试过程只能使用读入文件的方式测试不同方式转化成实体类的效率。

比较常用的方法

是直接用 com.alibaba.fastjson 下的JSONObject.parseObject将JSON字符串反序列化为Java对象的过程

 MyObject response = JSONObject.parseObject(dataStr, MyObject .class);
这样做简单便捷,但是有一个问题是当这个字符串dataStr很长很大的时候,这样做容易引起oom导致程序奔溃,或者响应时间太长,对及时性要求高的不适用。

以下是改写优化

版本一:使用readValue反序列化为Person对象,使用中发现它的效率比JSONObject.parseObject好一些,但是长文本也是捉襟见肘。

ObjectMapper objectMapper = new ObjectMapper();
Person person = objectMapper.readValue(json, Person.class);

版本二:将字符串解析为JsonNode对象,根据自己的需要获取对应的节点数据,它的效率比readValue更好些,但是比较麻烦,需要自己一个个节点取数据。

ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode= objectMapper.readTree(json);
if (rootNode.has("data")) {
    // 遍历对应的对象取数据
    ArrayList<ModelArea> modelList = new ArrayList<>();
    JsonNode dataArrayNode = rootNode.get("data");
    for (JsonNode timeDataNode : dataArrayNode) {
        // ...
    }
}
这种方法足以应付常规几M甚至即使M的json文件了,但是文件再大一些,又oom了

版本三:节点很多的情况增加流式处理,使用了elements()方法来获取JSON数组的元素流,并使用forEachRemaining()方法来遍历元素

 ObjectMapper objectMapper = new ObjectMapper();
 try {
     JsonNode rootNode = objectMapper.readTree(dataStr);
     List<ModelArea> timeDataList = new ArrayList<>();
     rootNode.get("data").elements().forEachRemaining(timeDataNode -> {
        // 第一层处理
        timeDataNode.get("data").elements().forEachRemaining(gridDataNode -> {
            // 第二层处理
        });

    });
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值