在平時的開發工做中,常常遇到這樣一個場景,在數據庫中存儲了具備父子關係的數據,須要將這些數據以樹形結構的形式在界面上進行展現。本文的目的是提供了一個通用的編程模型,解決將具備父子關係的數據轉換成樹形結構的問題。若有不正之處,歡迎你們批評指正。
編程模型
咱們以北京行政區劃爲例,講解整個模型。
北京市:市轄區 縣
市轄區:東城區 西城區 朝陽區 豐臺區 石景山區 海淀區 門頭溝區 房山區 通州區 順義區 昌平區 大興區 懷柔區 平谷區
縣:密雲縣 延慶縣
UML類圖以下:
Tree結構
TreeNode:定義樹的節點對象
nodeId:樹節點Id。
nodeName:樹節點名稱。
parentNodeId:樹節點父Id。
orderNum:節點在樹中的排序號,在同一節點下進行排序。
level:當前樹節點所在的層級,根節點爲第一層。
parent:當前樹節點的父節點。
children:當前樹節點的兒子節點。
allChildren:當前樹節點的子孫節點。
ITree:定義樹對象要實現的方法。
getTree():以 List 形式返回樹的全部的 TreeNode 對象。
getRoot():以 List 形式返回樹的根節點,多是一個或者多個。
getTreeNode(String nodeId):根據 nodeId 返回對應的 TreeNode 對象。
Tree:實現 ITree 接口,提供樹的完整功能。
getTree():以 List 形式返回樹的全部的 TreeNode 對象。
getRoot():以 List 形式返回樹的根節點,多是一個或者多個。
getTreeNode(String nodeId):根據 nodeId 返回對應的 TreeNode 對象。
ITreeNode:定義模板方法,構造樹形結構的類要實現該接口,Tree 經過調用該接口中的方法獲取 nodeId nodeName parentNodeId orderNum 數據。
getNodeId():獲取樹節點Id。
getNodeName():獲取樹節點名稱。
getParentNodeId():獲取樹節點父Id。
getOrderNum():獲取節點在樹中的排序號,在同一節點下進行排序。
Org:定義行政區劃類,實現 ItreeNode 接口。
--------------------- java
在平時的開發工做中,常常遇到這樣一個場景,在數據庫中存儲了具備父子關係的數據,須要將這些數據以樹形結構的形式在界面上進行展現。本文的目的是提供了一個通用的編程模型,解決將具備父子關係的數據轉換成樹形結構的問題。若有不正之處,歡迎你們批評指正。
編程模型
咱們以北京行政區劃爲例,講解整個模型。
北京市:市轄區 縣
市轄區:東城區 西城區 朝陽區 豐臺區 石景山區 海淀區 門頭溝區 房山區 通州區 順義區 昌平區 大興區 懷柔區 平谷區
縣:密雲縣 延慶縣
UML類圖以下:
Tree結構
TreeNode:定義樹的節點對象
nodeId:樹節點Id。
nodeName:樹節點名稱。
parentNodeId:樹節點父Id。
orderNum:節點在樹中的排序號,在同一節點下進行排序。
level:當前樹節點所在的層級,根節點爲第一層。
parent:當前樹節點的父節點。
children:當前樹節點的兒子節點。
allChildren:當前樹節點的子孫節點。
ITree:定義樹對象要實現的方法。
getTree():以 List 形式返回樹的全部的 TreeNode 對象。
getRoot():以 List 形式返回樹的根節點,多是一個或者多個。
getTreeNode(String nodeId):根據 nodeId 返回對應的 TreeNode 對象。
Tree:實現 ITree 接口,提供樹的完整功能。
getTree():以 List 形式返回樹的全部的 TreeNode 對象。
getRoot():以 List 形式返回樹的根節點,多是一個或者多個。
getTreeNode(String nodeId):根據 nodeId 返回對應的 TreeNode 對象。
ITreeNode:定義模板方法,構造樹形結構的類要實現該接口,Tree 經過調用該接口中的方法獲取 nodeId nodeName parentNodeId orderNum 數據。
getNodeId():獲取樹節點Id。
getNodeName():獲取樹節點名稱。
getParentNodeId():獲取樹節點父Id。
getOrderNum():獲取節點在樹中的排序號,在同一節點下進行排序。
Org:定義行政區劃類,實現 ItreeNode 接口。
實現代碼
TreeNode類:
package com.ips.tree;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
/**
* <p>Title: 樹節點</p>
* <p>Description:一棵樹由許多包含父子關係的節點組成 </p>
* @author liuzhibo
* @date 2017年1月18日
*/
public class TreeNode {
//樹節點ID
@JSONField(ordinal=1)
private String nodeId;
//樹節點名稱
@JSONField(ordinal=2)
private String nodeName;
//父節點ID
@JSONField(ordinal=3)
private String parentNodeId;
//節點在樹中的排序號
@JSONField(ordinal=4)
private int orderNum;
//節點所在的層級
@JSONField(ordinal=5)
private int level;
private TreeNode parent;
//當前節點的二子節點
@JSONField(ordinal=6)
private List<TreeNode> children = new ArrayList<TreeNode>();
//當前節點的子孫節點
private List<TreeNode> allChildren = new ArrayList<TreeNode>();
public TreeNode(ITreeNode obj){
this.nodeId = obj.getNodeId();
this.nodeName = obj.getNodeName();
this.parentNodeId = obj.getNodeParentId();
this.orderNum = obj.getOrderNum();
}
public void addChild(TreeNode treeNode){
this.children.add(treeNode);
}
public void removeChild(TreeNode treeNode){
this.children.remove(treeNode);
}
public String getNodeId() {
return nodeId;
}
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public String getParentNodeId() {
return parentNodeId;
}
public void setParentNodeId(String parentNodeId) {
this.parentNodeId = parentNodeId;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public List<TreeNode> getChildren() {
return children;
}
public void setChildren(List<TreeNode> children) {
this.children = children;
}
public int getOrderNum() {
return orderNum;
}
public void setOrderNum(int orderNum) {
this.orderNum = orderNum;
}
public List<TreeNode> getAllChildren() {
if(this.allChildren.isEmpty()){
for(TreeNode treeNode : this.children){
this.allChildren.add(treeNode);
this.allChildren.addAll(treeNode.getAllChildren());
}
}
return this.allChildren;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
ITree接口:
package com.ips.tree;
import java.util.List;
public interface ITree {
public List<TreeNode> getTree();
public List<TreeNode> getRoot();
public TreeNode getTreeNode(String nodeId);
}
1
2
3
4
5
6
7
8
9
Tree類:
package com.ips.tree;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
public class Tree implements ITree {
private HashMap<String, TreeNode> treeNodesMap = new HashMap<String, TreeNode>();
private List<TreeNode> treeNodesList = new ArrayList<TreeNode>();
public Tree(List<ITreeNode> list){
initTreeNodeMap(list);
initTreeNodeList();
}
private void initTreeNodeMap(List<ITreeNode> list){
TreeNode treeNode = null;
for(ITreeNode item : list){
treeNode = new TreeNode(item);
treeNodesMap.put(treeNode.getNodeId(), treeNode);
}
Iterator<TreeNode> iter = treeNodesMap.values().iterator();
TreeNode parentTreeNode = null;
while(iter.hasNext()){
treeNode = iter.next();
if(treeNode.getParentNodeId() == null || treeNode.getParentNodeId() == ""){
continue;
}
parentTreeNode = treeNodesMap.get(treeNode.getParentNodeId());
if(parentTreeNode != null){
treeNode.setParent(parentTreeNode);
parentTreeNode.addChild(treeNode);
}
}
}
private void initTreeNodeList(){
if(treeNodesList.size() > 0){
return;
}
if(treeNodesMap.size() == 0){
return;
}
Iterator<TreeNode> iter = treeNodesMap.values().iterator();
TreeNode treeNode = null;
while(iter.hasNext()){
treeNode = iter.next();
if(treeNode.getParent() == null){
this.treeNodesList.add(treeNode);
this.treeNodesList.addAll(treeNode.getAllChildren());
}
}
}
@Override
public List<TreeNode> getTree() {
return this.treeNodesList;
}
@Override
public List<TreeNode> getRoot() {
List<TreeNode> rootList = new ArrayList<TreeNode>();
if (this.treeNodesList.size() > 0) {
for (TreeNode node : treeNodesList) {
if (node.getParent() == null)
rootList.add(node);
}
}
return rootList;
}
@Override
public TreeNode getTreeNode(String nodeId) {
return this.treeNodesMap.get(nodeId);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
ITreeNode 接口:
package com.ips.tree;
public interface ITreeNode {
public String getNodeId();
public String getNodeName();
public String getNodeParentId();
public Integer getOrderNum();
}
1
2
3
4
5
6
7
8
Org 類:
package com.ips.tree;
public class Org implements ITreeNode {
private String uuid;
private String parentId;
private String name;
private Integer orderNum;
private String code;
private String type;
public Org(){
}
public Org(String uuid, String parentId, String name, Integer orderNum, String code, String type){
this.uuid = uuid;
this.parentId = parentId;
this.name = name;
this.orderNum = orderNum;
this.code = code;
this.type = type;
}
@Override
public String getNodeId() {
return this.uuid;
}
@Override
public String getNodeName() {
return this.name;
}
@Override
public String getNodeParentId() {
return this.parentId;
}
@Override
public Integer getOrderNum() {
return this.orderNum;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void setOrderNum(Integer orderNum) {
this.orderNum = orderNum;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
TreeDemo 類:執行該類的 main 方法,查看效果。
package com.ips.tree;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
public class TreeDemo {
public static void main(String[] args) {
Tree tree = new Tree(genOrgList());
TreeNode treeNode = tree.getTreeNode("2");
SimplePropertyPreFilter filter = new SimplePropertyPreFilter(); // 構造方法裏,也能夠直接傳須要序列化的屬性名字
filter.getExcludes().add("parent");
filter.getExcludes().add("allChildren");
String data = JSONObject.toJSONString(treeNode, filter);
System.out.println(data);
}
public static List<ITreeNode> genOrgList(){
List<ITreeNode> list = new ArrayList<ITreeNode>();
Org org = new Org("2", "1", "北京市", 2, "110000", "2");
list.add(org);
org = new Org("3", "2", "市轄區", 3, "110100", "3");
list.add(org);
org = new Org("4", "3", "東城區", 4, "110101", "4");
list.add(org);
org = new Org("5", "3", "東城區", 5, "110102", "4");
list.add(org);
org = new Org("6", "3", "東城區", 6, "110105", "4");
list.add(org);
org = new Org("7", "3", "東城區", 7, "110106", "4");
list.add(org);
org = new Org("8", "3", "東城區", 8, "110107", "4");
list.add(org);
org = new Org("9", "3", "東城區", 9, "110108", "4");
list.add(org);
org = new Org("10", "3", "東城區", 10, "110109", "4");
list.add(org);
org = new Org("11", "3", "東城區", 11, "110111", "4");
list.add(org);
org = new Org("12", "3", "東城區", 12, "110112", "4");
list.add(org);
org = new Org("13", "3", "東城區", 13, "110113", "4");
list.add(org);
org = new Org("14", "3", "東城區", 14, "110114", "4");
list.add(org);
org = new Org("15", "3", "東城區", 15, "110115", "4");
list.add(org);
org = new Org("16", "3", "東城區", 16, "110116", "4");
list.add(org);
org = new Org("17", "3", "東城區", 17, "110117", "4");
list.add(org);
org = new Org("18", "2", "縣", 3, "110200", "3");
list.add(org);
org = new Org("19", "18", "密雲縣", 19, "110228", "4");
list.add(org);
org = new Org("20", "18", "延慶縣", 20, "110229", "4");
list.add(org);
return list;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
執行結果以下:
{
"nodeId": "2",
"nodeName": "北京市",
"parentNodeId": "1",
"orderNum": 2,
"level": 0,
"children": [{
"nodeId": "18",
"nodeName": "縣",
"parentNodeId": "2",
"orderNum": 3,
"level": 0,
"children": [{
"nodeId": "19",
"nodeName": "密雲縣",
"parentNodeId": "18",
"orderNum": 19,
"level": 0,
"children": []
},
{
"nodeId": "20",
"nodeName": "延慶縣",
"parentNodeId": "18",
"orderNum": 20,
"level": 0,
"children": []
}]
},
{
"nodeId": "3",
"nodeName": "市轄區",
"parentNodeId": "2",
"orderNum": 3,
"level": 0,
"children": [{
"nodeId": "17",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 17,
"level": 0,
"children": []
},
{
"nodeId": "15",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 15,
"level": 0,
"children": []
},
{
"nodeId": "16",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 16,
"level": 0,
"children": []
},
{
"nodeId": "13",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 13,
"level": 0,
"children": []
},
{
"nodeId": "14",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 14,
"level": 0,
"children": []
},
{
"nodeId": "11",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 11,
"level": 0,
"children": []
},
{
"nodeId": "12",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 12,
"level": 0,
"children": []
},
{
"nodeId": "10",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 10,
"level": 0,
"children": []
},
{
"nodeId": "7",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 7,
"level": 0,
"children": []
},
{
"nodeId": "6",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 6,
"level": 0,
"children": []
},
{
"nodeId": "5",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 5,
"level": 0,
"children": []
},
{
"nodeId": "4",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 4,
"level": 0,
"children": []
},
{
"nodeId": "9",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 9,
"level": 0,
"children": []
},
{
"nodeId": "8",
"nodeName": "東城區",
"parentNodeId": "3",
"orderNum": 8,
"level": 0,
"children": []
}]
}]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
注:該示例中使用了 alibaba 的 fastjson 實現類對象序列化,maven 依賴以下:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.20</version>
</dependency>
---------------------
做者:zhiboer
來源:CSDN
原文:https://blog.csdn.net/claram/article/details/54616485
版權聲明:本文爲博主原創文章,轉載請附上博文連接!node