如何把一个平面的节点转换成树节点。
工作中遇到,要求把一个平面的数据转换成一棵树的结构数据,返回给前端或者第三方。
比如我们有个对象实体 House,包含的属性有 楼栋-单元-楼层-室号 这四个基本属性。
但是这四个属性刚好也是从上到下可构造树状结构,构成一棵树。
我们就是需要把一个个的House对象构造成树状结构的数据,返回。
怎么做呢 ?
直接上一段代码,大家参考下:
我们这里有2个实体对象,一个是House对象就是相当于从数据库中查询的数据,扁平的数据,现在就是要把House数据转换成树状结构。HouseTreeNode 就是转换后的实体对象, 树状结构对象。 House -> HouseTreeNode 的转换过程:
转换成树状结构:
@Data
public class HouseTreeNode {
private Long houseId;
private String name;
private String houseType;
private Long houseTypeId;
private String parentNodeName;
private List<HouseTreeNode> children;
private int level;
private boolean leaf;
// private List<TaskResponse> tasks;
}
@Data
public class House {
private Long id;
private Long houseTypeId;
private String houseTypeName;
private String building;
private String unit;
private String floor;
private String room;
private Long projectId;
}
public class TreeConvert {
//
public static List<HouseTreeNode> convertToHouseTree(List<House> houses, Map<BigInteger) {
List<HouseTreeNode> list = new ArrayList<>();
String parentNodeName = "";
for (House house : houses) {
parentNodeName = house.getHouseTypeName();
//楼栋
HouseTreeNode buildNode = getNode(list, house.getBuilding(), parentNodeName);
buildNode.setLevel(1);
buildNode.setHouseTypeId(house.getHouseTypeId());
//单元
parentNodeName = buildNode.getName();
HouseTreeNode unitNode = getNode(buildNode.getChildren(), house.getUnit(), parentNodeName);
unitNode.setLevel(2);
//楼层
parentNodeName = parentNodeName + "-" + unitNode.getName();
HouseTreeNode floorNode = getNode(unitNode.getChildren(), house.getFloor(), parentNodeName);
floorNode.setLevel(3);
// 户号
parentNodeName = parentNodeName + "-" + floorNode.getName();
HouseTreeNode houseNode = getNode(floorNode.getChildren(), house.getRoom(), parentNodeName);
houseNode.setLevel(4);
//户号-2
parentNodeName = parentNodeName + "-" + houseNode.getName();
List<HouseTreeNode> roomList = houseNode.getChildren();
HouseTreeNode houseNodeData = new HouseTreeNode();
BeanUtils.copyProperties(house,houseNodeData);
houseNodeData.setLevel(5);
houseNodeData.setLeaf(true);
houseNodeData.setName(house.getRoom());
houseNodeData.setParentNodeName(parentNodeName);
houseNodeData.setHouseId(house.getId());
houseNodeData.setHouseType(house.getHouseTypeName());
houseNodeData.setHouseTypeId(house.getHouseTypeId());
// if (taskResponseMap != null && !taskResponseMap.isEmpty()) {
//houseNodeData.setTasks(taskResponseMap.get(BigInteger.valueOf(house.getId())));
// }
roomList.add(houseNodeData);
}
return list;
}
public static HouseTreeNode getNode(List<HouseTreeNode> nodeList, String nodeName, String parentNodeName) {
Optional<HouseTreeNode> existNode = isExistNode(nodeList, nodeName);
HouseTreeNode node;
if (existNode.isPresent()) {
node = existNode.get();
} else {
node = new HouseTreeNode();
node.setName(nodeName);
node.setParentNodeName(parentNodeName);
node.setChildren(new ArrayList<>());
nodeList.add(node);
}
return node;
}
public static Optional<HouseTreeNode> isExistNode(List<HouseTreeNode> list, String nodeName) {
Optional<HouseTreeNode> opt = list.stream().filter(h -> h.getName().equals(nodeName)).findFirst();
return opt;
}
}
对上面的代码进行本地测试:
public static void main(String[] args) {
List<House> houses = new ArrayList<>();
House house1 = new House();
house1.setId(1L); house1.setHouseTypeId(100L); house1.setHouseTypeName("A");
house1.setBuilding("1栋");house1.setUnit("3单元");house1.setFloor("2楼");house1.setRoom("203");
House house2 = new House();
house2.setId(2L); house2.setHouseTypeId(100L); house2.setHouseTypeName("A");
house2.setBuilding("1栋");house2.setUnit("3单元");house2.setFloor("2楼");house2.setRoom("206");
House house3 = new House();
house3.setId(3L); house3.setHouseTypeId(100L); house3.setHouseTypeName("A");
house3.setBuilding("2栋");house3.setUnit("10单元");house3.setFloor("6楼");house3.setRoom("601");
houses.add(house1);
houses.add(house2);
houses.add(house3);
List<HouseTreeNode> houseTreeNodes = convertToHouseTree(houses);
log.info("houseTreeNodes size:{}", houseTreeNodes.size());
String s = JSON.toJSONString(houseTreeNodes);
log.info("s: {}", s);
}
输出的数据内容格式:
[{
"children": [{
"children": [{
"children": [{
"children": [{
"houseId": 1,
"houseType": "A",
"houseTypeId": 100,
"leaf": true,
"level": 5,
"name": "203",
"parentNodeName": "1栋-3单元-2楼-203"
}],
"leaf": false,
"level": 4,
"name": "203",
"parentNodeName": "1栋-3单元-2楼"
},
{
"children": [{
"houseId": 2,
"houseType": "A",
"houseTypeId": 100,
"leaf": true,
"level": 5,
"name": "206",
"parentNodeName": "1栋-3单元-2楼-206"
}],
"leaf": false,
"level": 4,
"name": "206",
"parentNodeName": "1栋-3单元-2楼"
}],
"leaf": false,
"level": 3,
"name": "2楼",
"parentNodeName": "1栋-3单元"
}],
"leaf": false,
"level": 2,
"name": "3单元",
"parentNodeName": "1栋"
},
{
"children": [{
"children": [{
"children": [{
"houseId": 3,
"houseType": "A",
"houseTypeId": 100,
"leaf": true,
"level": 5,
"name": "601",
"parentNodeName": "1栋-10单元-6楼-601"
}],
"leaf": false,
"level": 4,
"name": "601",
"parentNodeName": "1栋-10单元-6楼"
}],
"leaf": false,
"level": 3,
"name": "6楼",
"parentNodeName": "1栋-10单元"
}],
"leaf": false,
"level": 2,
"name": "10单元",
"parentNodeName": "1栋"
}],
"houseTypeId": 100,
"leaf": false,
"level": 1,
"name": "1栋",
"parentNodeName": "A"
}]