背景
有一個接口會返回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;
}