背景
有一个接口会返回json格式的字符串,json格式是嵌套的,类似这样的如下的结构,需要转换为一个list,当然最简单的写一个递归就可以了,但是有一句话: “所有的递归都可以转化为循环”,那么就练练自己的代码能力,温故而知新,用循环实现吧。
{
"respData":[
{
"id":1,
"isvalid":1,
"orgName":"汽车",
"parentId":0,
"subOrgList":[
{
"id":33,
"isvalid":1,
"orgName":"客车",
"parentId":1,
"subOrgList":[
{
"id":37,
"isvalid":1,
"orgName":"大客车",
"parentId":33
},
{
"id":38,
"isvalid":1,
"orgName":"小客车",
"parentId":33
}
]
},
{
"id":88,
"isvalid":1,
"orgName":"SUV",
"parentId":1
}
]
},
{
"id":2,
"isvalid":1,
"orgName":"自行车",
"parentId":0,
"subOrgList":[
{
"id":56,
"isvalid":1,
"orgName":"永久",
"parentId":2
}
]
},
{
"id":4,
"isvalid":1,
"orgName":"地铁",
"parentId":0
}
],
"respCode":"0"
}
原理
假如有如下图所示的json结构字符串,整个结构为jsonArray,蓝色框中的时jsonArray1,红色框中的时jsonArray2,jsonArray1中有jsonArray11和jsonArray12,jsonArray11中有jsonArray111。
栈为先入后出
- 第一次循环:把1、2、3、4、5、6、7、8的节点信息放到结果list中,并把jsonArray1、jsonArray2放到栈中;
- 第二次循环:循环jsonArray2,把711、712放入结果list中;
- 第三次循环:循环jsonArray1,把jsonArray11和jsonArray12放入栈中;
- 第四次循环:jsonArray12,把121、122放入结果list中;
- 第五次循环:循环jsonArray11,把111、112、113、114放到结果list中,jsonArray111放入栈中;
- 第六次循环:循环jsonArray111,把1111、1112放入结果list中。
代码
public class SelectionEntity {
private String id;
private String text;
public SelectionEntity(String id, String text) {
this.id = id;
this.text = text;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public String toString() {
return "SelectionEntity{" +
"id='" + id + '\'' +
", text='" + text + '\'' +
'}';
}
}
public List<SelectionEntity> companyAll() {
List<SelectionEntity> selectionEntities = new ArrayList<>();
loggerHelper.info("接口返回成功,开始转换");
// 省略了获取json格式内容的调用
String content = "{\"respData\":[{\"id\":1,\"isvalid\":1,\"orgName\":\"汽车\",\"parentId\":0,\"subOrgList\":[{\"id\":33,\"isvalid\":1,\"orgName\":\"客车\",\"parentId\":1,\"subOrgList\":[{\"id\":37,\"isvalid\":1,\"orgName\":\"大客车\",\"parentId\":33},{\"id\":38,\"isvalid\":1,\"orgName\":\"小客车\",\"parentId\":33}]},{\"id\":88,\"isvalid\":1,\"orgName\":\"SUV\",\"parentId\":1}]},{\"id\":2,\"isvalid\":1,\"orgName\":\"自行车\",\"parentId\":0,\"subOrgList\":[{\"id\":56,\"isvalid\":1,\"orgName\":\"永久\",\"parentId\":2}]},{\"id\":4,\"isvalid\":1,\"orgName\":\"地铁\",\"parentId\":0}],\"respCode\":\"0\"}";
JSONObject jsonObject = JSONObject.parseObject(content);
JSONArray jsonArray = jsonObject.getJSONArray("respData");
String hasSubOrgKey = "subOrgList";
Stack<TreeStruct> structStack = new Stack<>();
// 当前jsonArray放入栈中
structStack.push(new TreeStruct("", jsonArray));
do {
// 从栈中获取
TreeStruct struct = structStack.pop();
String parentName = struct.getCurrentName();
// 遍历jsonArray
for (int i = 0, jsonArray = struct.getJsonArray(); i < jsonArray.size(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
// 当前对象的名称由父节点名称和当前节点名称拼装而成
String name = jsonObject1.getString("orgName");
if (!parentName.isEmpty()) {
name = String.join("-", parentName, name);
}
// 如果当前节点有 子列表
if (jsonObject1.containsKey(hasSubOrgKey) && jsonObject1.getJSONArray(hasSubOrgKey).size() > 0) {
// 子列表放入栈中
structStack.push(new TreeStruct(name, jsonObject1.getJSONArray(hasSubOrgKey)));
}
String orgId = jsonObject1.getString("id");
// 当前对象放入结果list中
selectionEntities.add(new SelectionEntity(orgId, name));
}
// 当前栈中有内容就继续循环
} while (!structStack.empty());
loggerHelper.info("转换完成,size:", selectionEntities.size());
return selectionEntities;
}
来源:CSDN
作者:ssshen14
链接:https://blog.csdn.net/ssshen14/article/details/104431031