在我们工作中经常会遇到一些树形结构的数据,比如机构组织树,这个时候我们就需要拼装树形结构的数据,返回给前端。
1.首先准备数据(数据中一定会包括主键、名称、父节点)
/**
* 树形数据
*/
@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);
2.返回前端的对象
/**
* 树形结构Vo
*/
@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);
}
}
3.拼装数据
- 定义返回前端的list
List<TreeVo> resultList = new ArrayList<>();
- 定义存放所有树形结构数据的map
Map<String, TreeVo> map = new HashMap<>();
- 树形结构转换类
/**
* 树形结构转换类
*/
@Mapper
public interface TreeConvert {
TreeConvert INSTANCE = Mappers.getMapper(TreeConvert.class);
/**
*TreeData转换成TreeVo
* @param treeData
* @return
*/
TreeVo treeDataToTreeVo(TreeData treeData);
}
思路:
共两次循环,第一次循环准备好的树形结构数据,将没有父节点的放在返回前端的list中,将所有的数据转换成返回前端的vo,并存在map中。第二次循环,如果有父节点,从map中取出父节点,将子节点添加到父节点的孩子中(child),注意如果有父节点还要判断父节点是否在第一次循环的list中,避免脏数据。
@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);
}
}
搞定下班