非科班出身,欢迎指正。
要实现的逻辑是,在一棵树中,给出任意一个节点,获取到该节点下的N个层级。
一.树型结构
下图的树中,节点上的字母代表节点的名字,字母下的代表该节点的下单金额。

二.数据准备
组装数据
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;
}
}
编写逻辑
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; } }
三.测试
按照图中的树形结构,以K节点举例,遍历得到K节点下的3个层级,输出的字符串为:
{"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"}]}
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 }
