“樹”這個結構,在計算機中應該是無處不在的。例如文件目錄樹,數據庫樹索引,組織機構樹等等。對於JavaWeb開發工程師來說,比較常見的有菜單樹,權限樹,組織機構樹等。這些樹形結構的每一個節點通常是存在數據庫表中的,並且每一個節點都是一條獨立的數據。如下,這里規定pid為null的時候,為根節點
那么如何將這樣的列表數據封裝為樹形結構的數據呢?結構如下
[ { "id": "0", "pid": null, "name": "全國", "children": [ { "id": "1", "pid": "0", "name": "廣東省", "children": [ { "id": "4", "pid": "1", "name": "佛山市", "children": [ ] }, { "id": "5", "pid": "1", "name": "汕頭市", "children": [ ] }, { "id": "6", "pid": "1", "name": "東莞市", "children": [ ] } ] }, { "id": "2", "pid": "0", "name": "湖北省", "children": [ { "id": "7", "pid": "2", "name": "黃岡市", "children": [ ] }, { "id": "8", "pid": "2", "name": "宜昌市", "children": [ ] }, { "id": "9", "pid": "2", "name": "襄陽市", "children": [ ] } ] }, { "id": "3", "pid": "0", "name": "河南省", "children": [ { "id": "10", "pid": "3", "name": "洛陽市", "children": [ ] }, { "id": "11", "pid": "3", "name": "開封市", "children": [ ] }, { "id": "12", "pid": "3", "name": "新鄉市", "children": [ ] } ] } ] } ]
代碼如下
1,節點類
package net.sunmonkey.datatotree; import java.util.LinkedList; import java.util.List; /** * 樹結構節點對象類 * @author Wenqin Cheng */ public class NodeVo { private String id; private String pid; private String name; private List<NodeVo> children; public NodeVo() { children = new LinkedList<>(); } public NodeVo(String id, String pid, String name) { this.id = id; this.pid = pid; this.name = name; this.children = new LinkedList<>(); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPid() { return pid; } public void setPid(String pid) { this.pid = pid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<NodeVo> getChildren() { return children; } public void setChildren(List<NodeVo> children) { this.children = children; } @Override public String toString() { return "NodeVo{" + "id='" + id + '\'' + ", pid='" + pid + '\'' + ", name='" + name + '\'' + ", children=" + children + '}'; } }
2,轉換工具類
package net.sunmonkey.datatotree; import java.util.LinkedList; import java.util.List; /** * id,pid的列表數據轉化為樹形結構數據 * @author Wenqin Cheng */ public class ConvertUtil { public static List<NodeVo> getTreeData(List<NodeVo> list) { List<NodeVo> tree = new LinkedList<>(); if(null != list && !list.isEmpty()){ for(NodeVo nodeVo: list){ addToTreeNodeList(list, nodeVo); } for (NodeVo nodeVo: list){ if(null == nodeVo.getPid()){ tree.add(nodeVo); } } } return tree; } private static void addToTreeNodeList(final List<NodeVo> nodeVoList, NodeVo treeNodeVo){ if(null != nodeVoList && !nodeVoList.isEmpty()){ for(NodeVo parentNodeVo: nodeVoList){ if(parentNodeVo.getId().equals(treeNodeVo.getPid())){ List<NodeVo> children = parentNodeVo.getChildren(); boolean flag = true; for(NodeVo node: children){ if(treeNodeVo.getId().equals(node.getId())){ flag = false; } } if(flag){ children.add(treeNodeVo); } break; }else{ addToTreeNodeList(parentNodeVo.getChildren(), treeNodeVo); } } } } }
3,測試主方法
package net.sunmonkey.datatotree; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.LinkedList; import java.util.List; /** * 主方法 * @author Wenqin Cheng */ public class MainClass { static ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) throws Exception { List<NodeVo> list = new LinkedList<>(); list.add(new NodeVo("0", null, "全國")); list.add(new NodeVo("1", "0", "廣東省")); list.add(new NodeVo("2", "0", "湖北省")); list.add(new NodeVo("3", "0", "河南省")); list.add(new NodeVo("4", "1", "佛山市")); list.add(new NodeVo("5", "1", "汕頭市")); list.add(new NodeVo("6", "1", "東莞市")); list.add(new NodeVo("7", "2", "黃岡市")); list.add(new NodeVo("8", "2", "宜昌市")); list.add(new NodeVo("9", "2", "襄陽市")); list.add(new NodeVo("10", "3", "洛陽市")); list.add(new NodeVo("11", "3", "開封市")); list.add(new NodeVo("12", "3", "新鄉市")); System.out.println("轉換前數據:"); System.out.println(objectMapper.writeValueAsString(list)); List<NodeVo> result = ConvertUtil.getTreeData(list); System.out.println("轉換后數據:"); System.out.println(objectMapper.writeValueAsString(result)); } }