遞歸調用轉爲循環

背景

有一個接口會返回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. 第一次循環:把1、2、3、4、5、6、7、8的節點信息放到結果list中,並把jsonArray1、jsonArray2放到棧中;
  2. 第二次循環:循環jsonArray2,把711、712放入結果list中;
  3. 第三次循環:循環jsonArray1,把jsonArray11和jsonArray12放入棧中;
  4. 第四次循環:jsonArray12,把121、122放入結果list中;
  5. 第五次循環:循環jsonArray11,把111、112、113、114放到結果list中,jsonArray111放入棧中;
  6. 第六次循環:循環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;
}
發佈了51 篇原創文章 · 獲贊 4 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章