如何拼装树形结构数据呢?
上一篇文章描述了,但是过于业务,描述的是我遇到的业务场景,接下来来抽象一下,更方便理解。
- 首先准备数据(数据中一定会包括主键、名称、父节点)
/**
* 树形数据
* @author lsh
* @date 2022/5/7
*/
@Data
@Accessors(chain = true)
public class TreeData {
@ApiModelProperty(value = "主键")
private String key;
@ApiModelProperty(value = "父节点主键")
private String parentKey;
@ApiModelProperty(value = "名称")
private String title;
}
TreeData treeData1 = new TreeData();
treeData1.setKey("1")
.setTitle("我是一级节点");
TreeData treeData2 = new TreeData();
treeData2.setKey("1-2")
.setParentKey("1")
.setTitle("我是二级级节点");
TreeData treeData3 = new TreeData();
treeData3.setKey("1-2-3")
.setParentKey("1-2")
.setTitle("我是三级节点");
list.add(treeData1);
list.add(treeData2);
list.add(treeData3);
- 返回前端的对象
/**
* 树形结构Vo
* @author lsh
* @date 2022/5/7
*/
@Data
public class TreeVo {
@ApiModelProperty(value = "主键")
private String key;
@ApiModelProperty(value = "名称")
private String title;
@ApiModelProperty(value = "子集")
private List<TreeVo> children = new ArrayList<>();
public void addChild(TreeVo vo){
children.add(vo);
}
}
- 拼装数据
- 定义返回前端的list
List<TreeVo> resultList = new ArrayList<>();
- 定义存放所有树形结构数据的map
Map<String, TreeVo> map = new HashMap<>();
- 第一次循环准备好的树形结构数据,将没有父节点的放在返回前端的list中,将所有的数据转换成返回前端的vo,并存在map中。
/**
* 树形结构转换类
* @author lsh
* @date 2022/5/7
*/
@Mapper
public interface TreeConvert {
TreeConvert INSTANCE = Mappers.getMapper(TreeConvert.class);
/**
*TreeData转换成TreeVo
* @param treeData
* @return
*/
TreeVo treeDataToTreeVo(TreeData treeData);
}
for (TreeData treeData:list) {
TreeVo treeVo = TreeConvert.INSTANCE.treeDataToTreeVo(treeData);
map.put(treeData.getKey(),treeVo);
//将一级节点添加到返回的结果集中
if(null == treeData.getParentKey()){
resultList.add(treeVo);
}
}
- 第二次循环,如果有父节点,从map中取出父节点,将子节点添加到父节点的孩子中。
for (TreeData treeData:list){
if(null != treeData.getParentKey()){
if(null == map.get(treeData.getParentKey())){
log.warn("存在子节点没有父级节点!");
}else{
TreeVo parentTreeVo = map.get(treeData.getParentKey());
parentTreeVo.addChild(map.get(treeData.getKey()));
}
}
}
- demo
@RunWith(SpringJUnit4ClassRunner.class)
@Slf4j
public class TestTree {
private List<TreeData> list = new ArrayList<>();
@Test
public void testTree() {
TreeData treeData1 = new TreeData();
treeData1.setKey("1")
.setTitle("我是一级节点");
TreeData treeData2 = new TreeData();
treeData2.setKey("1-2")
.setParentKey("1")
.setTitle("我是二级级节点");
TreeData treeData3 = new TreeData();
treeData3.setKey("1-2-3")
.setParentKey("1-2")
.setTitle("我是三级节点");
list.add(treeData1);
list.add(treeData2);
list.add(treeData3);
Map<String, TreeVo> map = new HashMap<>();
List<TreeVo> resultList = new ArrayList<>();
for (TreeData treeData:list) {
TreeVo treeVo = TreeConvert.INSTANCE.treeDataToTreeVo(treeData);
map.put(treeData.getKey(),treeVo);
//将一级节点添加到返回的结果集中
if(null == treeData.getParentKey()){
resultList.add(treeVo);
}
}
for (TreeData treeData:list){
if(null != treeData.getParentKey()){
if(null == map.get(treeData.getParentKey())){
log.warn("存在子节点没有父级节点!");
}else{
TreeVo parentTreeVo = map.get(treeData.getParentKey());
parentTreeVo.addChild(map.get(treeData.getKey()));
}
}
}
System.out.println(resultList);
}
}