关于接口复杂JSON解析
需求背景 通过上游接口获取数据 并对数据进行相应的解析及统计 将所有单元合并 并合并各个属性 单元属性拼接
测试代码下载地址(包含lambda基础测试类帮助理解):
分析1
动不动几千行的数据一定要先弄清机构层次
1.首先通过idea插件将请求回来的接口返回数据 格式化层实体对象
2.分析结构 找出 唯一标识 需要统计字段 集合
3.分析要统计的层级 即如图的各个单元的层级需要合并 其子目录的的每个对象都要合并成一个 也就是合并成一个单元
4.各个单元的子孙结构是相同的 需要合并的话常规流程一层层的合并 非集合字段要么拼接 要么取其一(唯一标识) 要么舍弃
集合的话就传入各个单元的集合到合并子集合方法中进行合并 这样的方法比较保险但是方法会比较多 针对这一个需求的话肯定没问题,但是感觉费时费力 还容易出差错 如下图 这些主体方法
分析总结:
虽然需求结束了 结果也正常但是后面还有这样的JSON肯定重复造轮子
想写个工具类 通过字段来直接获取该种JSON数据的合并统计结果 还不能和实体类相关 于是考虑使用JOSN类、、解耦
可变性强 其他的复杂数据结构也可根据该工具 进行改造复用
/**
- @program: 该模型用于统计数据底层模型 可以根据实际数据对响应字段进行增加 为底层数据目录层
- 上层还有节点 可单独使用类包裹 上上级获取上级的hashMap结果集
- 统计的话
- 1 先全局分析
-
1.1 先找到下层结构的第一个需要统计的对象的list集合(假设第一层中的属性集合就是需要统计的集合)
-
1.2 合并集合中需要统计的属性value 通过stream流获取集合中指定统计key的value求和 `double sum = list.stream().mapToDouble(x -> x.getNeedSumCol()).sum();`
-
1.3 合并集合(集合的集合 将多个集合合并成一个集合 即List<List<Obj>> ---> List<Obj>) set到集合属性
- (统计集合中各个对象 每个集合中的对象属性唯一标识(key)的value值一一对应
-
-
不对应但需要合并也可以,可以直接将相同key的value值拼接成字符在合并下层具有相同结构的集合)
-
- 2 集合合并方法 入参集合List<List> listIn 出参合并后的集合List listOut (核心)
-
2.1 打散listIn 双层变单层(遍历listIn 装入新的集合 ListEx<Obj> listEx 中 )
-
2.2 先将入参的集单层集合listEx进行分组 得到多个不同唯一标识需要统计的组合 HashMap<String,List>
-
通过stream 流 map方法 获取集合字段属性中的集合 得到唯一标识为key的map对象(HashMap<String,List>)
-
`Map<String,List> = list.stream.collect(Collector.groupingBy(Data::getNodeKey))`
-
2.3 创建集合listOut 用于收集map元素value值合并后的集合
for(String key::map.keySet()){
* List<Data> list = map.get(key)
* Data dataNew = new DataNew();
* DataNew.setNodeName(map.get(key).get(0));//默认相同的key随便取一个
* double sum = list.stream().mapToDouble(x -> x.getNeedSumCol()).sum();//求和
* dataNew.setNeedSumCol(sum)
* dataNew.setList(getNList-1List(list.stream.map(x->x.getListCol()).collect(Collector.toList)))
* listOut.add(dataNew)
* }
- 3 又回到2.1步骤了。。
- @Date: 2021/11/26 14:49
- @Author: Mr.Zzc
- @Description:
*/
上面的注释简单看下 不必在意 个人理解不同 合并的核心 多集合的集合 变成单集合的集合 get(0) 返回单集合
由于是远程 搞不下来数据 我这边手动构造生成了数据 详情见代码 代码中包含一些lambda基础的测试类及详解
其中JSON解析相关在LambdaUtil中 就这一个类
测试代码
public static void main(String[] args) {
GeneralTallyResDate genneral = new GeneralTallyResDate();
TallyResSimpleDate testData = genneral.getTallyResSimpleDate();
// String jsonS = JSONObject.toJSONString(testData);
List<TallyResSimpleDate.TallyResSplits> listSplit = testData.getTallyResSplits();
List listRes = LambdaUil.getBottomUpTwoFloor(
listSplit,
Arrays.asList("splitCode","splitName","tallyResCurrencies"),
Arrays.asList("currency","splitTallyDatas"),
Arrays.asList("nodeName","tallyAmount","data"));
System.out.println(listRes.size());
}
合并后的数据
代码下载地址: