非科班出身,歡迎指正。java
要實現的邏輯是,在一棵樹中,給出任意一個節點,獲取到該節點下的N個層級。node
一.樹型結構apache
下圖的樹中,節點上的字母表明節點的名字,字母下的表明該節點的下單金額。json
二.數據準備測試
組裝數據this
package ATree; import java.util.ArrayList; import java.util.List; public class PreData { public static List<NodeOrder> getData(){ NodeOrder A = new NodeOrder("0", "A","-1","123"); NodeOrder B = new NodeOrder("1", "B","0","10"); NodeOrder C = new NodeOrder("2", "C","0","20"); NodeOrder D = new NodeOrder("3", "D","0","30"); NodeOrder E = new NodeOrder("4", "E","1","40"); NodeOrder F = new NodeOrder("5", "F","3","50"); NodeOrder G = new NodeOrder("6", "G","3","60"); NodeOrder H = new NodeOrder("7", "H","4","70"); NodeOrder I = new NodeOrder("8", "I","4","80"); NodeOrder J = new NodeOrder("9", "J","4","90"); NodeOrder K = new NodeOrder("10","K","6","100"); NodeOrder L = new NodeOrder("11","L","8","110"); NodeOrder M = new NodeOrder("12","M","10","120"); NodeOrder N = new NodeOrder("13","N","10","130"); NodeOrder O = new NodeOrder("14","O","12","140"); NodeOrder P = new NodeOrder("15","P","12","150"); NodeOrder Q = new NodeOrder("16","Q","13","160"); NodeOrder R = new NodeOrder("17","R","13","170"); NodeOrder S = new NodeOrder("18","S","13","180"); NodeOrder T = new NodeOrder("19","T","15","190"); NodeOrder U = new NodeOrder("20","U","15","200"); NodeOrder V = new NodeOrder("21","V","19","210"); NodeOrder W = new NodeOrder("22","W","19","220"); NodeOrder X = new NodeOrder("23","X","20","230"); NodeOrder Y = new NodeOrder("24","Y","20","240"); NodeOrder Z = new NodeOrder("25","Z","20","250"); List<NodeOrder> list = new ArrayList<>(); list.add(A); list.add(B); list.add(C); list.add(D); list.add(E); list.add(F); list.add(G); list.add(H); list.add(I); list.add(J); list.add(K); list.add(L); list.add(M); list.add(N); list.add(O); list.add(P); list.add(Q); list.add(R); list.add(S); list.add(T); list.add(U); list.add(V); list.add(W); list.add(X); list.add(Y); list.add(Z); return list; } }
package ATree; import java.math.BigDecimal; public class NodeOrder { private String id; private String tag; private String parentId; private BigDecimal orderAmount; public NodeOrder(String id, String tag, String parentId, String orderAmount) { this.id = id; this.tag = tag; this.parentId = parentId; this.orderAmount = new BigDecimal(orderAmount); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTag() { return tag; } public void setTag(String tag) { this.tag = tag; } public String getParentId() { return parentId; } public void setParentId(String parentId) { this.parentId = parentId; } public BigDecimal getOrderAmount() { return orderAmount; } public void setOrderAmount(BigDecimal orderAmount) { this.orderAmount = orderAmount; } }
編寫邏輯spa
package ATree; import com.alibaba.fastjson.JSON; import org.apache.commons.collections.CollectionUtils; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Test { //計算層級的最大值 public static final int MAX_LEVEL = 3; public static void main(String[] args) { Test test = new Test(); List<NodeOrder> list = PreData.getData(); test.start("10",list); } public void start(String id, List<NodeOrder> sources){ Map<String, List<NodeOrder>> parentMap = groupByParentId(sources); Map<String, List<NodeOrder>> levelMap = new HashMap<>(); getLevel(id, parentMap, levelMap, 1); System.out.println(JSON.toJSONString(levelMap)); } public void getLevel(String parentId,Map<String, List<NodeOrder>> parentMap,Map<String, List<NodeOrder>> levelMap,int count){ //根據parentId獲取節點 List<NodeOrder> nextLevel = parentMap.get(parentId); if(CollectionUtils.isEmpty(nextLevel)) return; String countStr = String.valueOf(count); List<NodeOrder> thisLevel = levelMap.get(countStr); if (CollectionUtils.isEmpty(thisLevel)) { levelMap.put(countStr, nextLevel); } else { thisLevel.addAll(nextLevel); levelMap.put(countStr, thisLevel); } count++; if(count > MAX_LEVEL) return; for (NodeOrder nodeOrder : nextLevel) { String tempParentId = nodeOrder.getId(); getLevel(tempParentId, parentMap, levelMap, count); } } //按父節點分組 public Map<String, List<NodeOrder>> groupByParentId(List<NodeOrder> sources){ Map<String, List<NodeOrder>> listGroupby = sources.parallelStream().collect(Collectors.groupingBy(NodeOrder::getParentId)); return listGroupby; } }
三.測試code
按照圖中的樹形結構,以K節點舉例,遍歷獲得K節點下的3個層級,輸出的字符串爲:
blog
{"1":[{"id":"12","orderAmount":120,"parentId":"10","tag":"M"},{"id":"13","orderAmount":130,"parentId":"10","tag":"N"}],"2":[{"id":"14","orderAmount":140,"parentId":"12","tag":"O"},{"id":"15","orderAmount":150,"parentId":"12","tag":"P"},{"id":"16","orderAmount":160,"parentId":"13","tag":"Q"},{"id":"17","orderAmount":170,"parentId":"13","tag":"R"},{"id":"18","orderAmount":180,"parentId":"13","tag":"S"}],"3":[{"id":"19","orderAmount":190,"parentId":"15","tag":"T"},{"id":"20","orderAmount":200,"parentId":"15","tag":"U"}]}ci
JSON結構爲:
1 { 2 "1": [ 3 { 4 "id": "12", 5 "orderAmount": 120, 6 "parentId": "10", 7 "tag": "M" 8 }, 9 { 10 "id": "13", 11 "orderAmount": 130, 12 "parentId": "10", 13 "tag": "N" 14 } 15 ], 16 "2": [ 17 { 18 "id": "14", 19 "orderAmount": 140, 20 "parentId": "12", 21 "tag": "O" 22 }, 23 { 24 "id": "15", 25 "orderAmount": 150, 26 "parentId": "12", 27 "tag": "P" 28 }, 29 { 30 "id": "16", 31 "orderAmount": 160, 32 "parentId": "13", 33 "tag": "Q" 34 }, 35 { 36 "id": "17", 37 "orderAmount": 170, 38 "parentId": "13", 39 "tag": "R" 40 }, 41 { 42 "id": "18", 43 "orderAmount": 180, 44 "parentId": "13", 45 "tag": "S" 46 } 47 ], 48 "3": [ 49 { 50 "id": "19", 51 "orderAmount": 190, 52 "parentId": "15", 53 "tag": "T" 54 }, 55 { 56 "id": "20", 57 "orderAmount": 200, 58 "parentId": "15", 59 "tag": "U" 60 } 61 ] 62 }