解析特殊结构的JSON

作者: 小怪兽打葫芦娃 | 来源:发表于2017-06-25 15:57 被阅读345次

    Android程序员面试宝典

    一般来说JSON的Key是已知的,如下所示:

    {
        "results": [
               {
                "id": 1,
                "name": "wangyuwei",
                "sexuality": "male"
            },
            {
                "id": 2,
                "name": "JeasonWong",
                "sexuality": "female"
            }
        ]
    }
    

    这样的JSON太容易解析了,但是有性能上的缺点,比如”id”,”name”,”sexuality”这些Key一直重复出现,一定程度上成为了冗余数据,那么问题来了,如何解决呢?参考以下JSON格式。

    {
        data: {
            snapshot: {
                fields: [
                    "open_px",
                    "high_px",
                    "low_px"
                ],
                600570.SS: [
                    47.08,
                    48.38,
                    45.88
                ],
                000001.SZ: [
                    11.02,
                    11.12,
                    10.88
                ]
            }
        }
    }
    

    这种JSON格式并不是很常见,但是我认为性能确实很强悍的。没有多余的Key,除了”fields”外,其余的Key都不是事先知道的,而”fields”里的Value确是与”fields”同级Key的Value一一对应,成为这些Value的Key。多么好的一个想法!
    那么问题来了,对于这种未知Key的JSON数组我们该如何下手呢?
    虽然不知道Key,但我们可以使用Iterator遍历一遍就行了。

    JSONObject jsonObj = new JSONObject(json).getJSONObject("data").getJSONObject("snapshot");
    Iterator keyIter = jsonObj.keys();
    

    这样一来,所有的Key都拿到了,但这个时候我们只拿到了最外层的Key,即”fields”,”600570.SS”,”000001.SZ”,而”fileds”里的Value还没取出,这些Value即将作为”600570.SS”,”000001.SZ”中Value的Key了(前面已经说了,又啰嗦一遍:))

    List list = new ArrayList();
    JSONArray fields = jsonObj.getJSONArray("fields");
    for (int i = 0; i < fields.length(); i++) {
        list.add(i, fields.getString(i));
    }
    

    现在”fields”中的Value全都取出来放到了list里。接着就是遍历刚才的keyIter了。

    while (keyIter.hasNext()) {
        String keys = (String) keyIter.next();
        JSONArray jsonArray = jsonObj.getJSONArray(keys);
        Map map = new HashMap();
        if (keys.equals("fields")) {
            continue;
        } else {
            for (int i = 0; i < jsonArray.length(); i++) {
                map.put(list.get(i), jsonArray.get(i));
            }
            HSStockEntity hsStockEntity = new HSStockEntity();
            hsStockEntity.setSymbol(keys);
            hsStockEntity.setOpen_px(Double.parseDouble(map.get("open_px").toString()));
            hsStockEntity.setHigh_px(Double.parseDouble(map.get("high_px").toString()));
            hsStockEntity.setLow_px(Double.parseDouble(map.get("low_px").toString()));
            listEntity.add(hsStockEntity);
        }
    }
    

    从以上代码可以看到,我按照keyIter的顺序拿到”600570.SS”,”000001.SZ”中的Value,然后把他们放到了map里,map的Key是”fields”的Value,而map的Value则是”600570.SS”或”000001.SZ”对应的Value。
    HSStockEntity我的一个Model,这样最后能把所有的hsStockEntity都放在listEntity的集合中了。
    需要特别注意的一点是keyIter取到的Key并一定与你看到的顺序是一样的,也就是”fields”,”600570.SS”,”000001.SZ”三个的顺序是不一定的,那么假如你的JSON数据源必须要按照一定的顺序显示,那你就得需要自己写一下Comparator了。比如我这里对high_px进行降序排序,如果相等时根据symbol再排。

    System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
    Collections.sort(listEntity, new Comparator<HSStockEntity>() {
        @Override
        public int compare(HSStockEntity entity, HSStockEntity t1) {
            if ((float) entity.getHigh_px() - (float) t1.getHigh_px() ==0) {
                return entity.getSymbol().compareTo(t1.getSymbol());
               } else if ((float) entity.getHigh_px() - (float) t1.getHigh_px() > 0) {;
               if (isRise) return -1;
                return 1;
             } else {
                  if (isRise) return 1;
                      return -1;
                }
            }
    });
    

    这样以来,对这种特殊结构的JSON解析就完成了。

    阅读原文

    • 欢迎关注微信公众号、长期为您推荐优秀博文、开源项目、视频

    • 微信公众号名称:Android干货程序员

    相关文章

      网友评论

        本文标题:解析特殊结构的JSON

        本文链接:https://www.haomeiwen.com/subject/vghrcxtx.html