构建Java树结构的三种实现方法
目录
- 一、准备工作
- 表结构
- 部分表数据
- 二、三种方式
- controller层
- 构建树结构工具类(三种方式)
- 执行结javascript果
- 总结
一、准备工作
表结构
CREATE TABLE `asset_classification` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id', `className` varchar(50) NOT NULL COMMENT '分类名', `status` tinyint(2) NOT NULL COMMENT '状态(0:使用中 1:停用)', `type` tinyint(2) NOT NULL COMMENT '类别(0:设备 1:物料 2:附件)', `writeable` tinyint(2) NOT NULL COMMENT '1:不可编辑 0:可编辑', `parentId` int(11) NOT NULL COMMENT '父类id', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=157 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT;
部分表数据

二、三种方式
- 原始递归
- 利用Java 8 Stream流进行处理(原理还是递归)
- Stream流升级构建
controller层
@RestController
public class TestController {
@Autowired
private AssetClassificationBiz assetClassificationBiz;
@GetMapping("/tree")
public HttpResponseTemp<?> getTree(){
List<AssetClassification> assetClassificationList = assetClassificationBiz.selectAll();
List<TreeUtil.TreeSelect> list = new ArrayList<>();
for (AssetClassification assetClassification : assetClassificationList) {
TreeUtil.TreeSelect treeSelect = new TreeUtil.TreeSelect();
treeSelect.setId(Convert.toLong(assetClassification.getId()));
treeSelect.setLabel(assetClassification.getClassName());
treeSelect.setParentId(Convert.toLong(assetClassification.getParentId()));
list.add(treeSelect);
}
//原始递归
List<TreeUtil.TreeSelect> list1 = TreeUtil.buildTree(list);
//利用Java 8 Stream流进行处理(原理还是递归)
List<TreeUtil.TreeSelect> list2 = TreeUtil.buildTreeByStream(list);
//Stream流升级构建
List<TreeUtil.TreeSelect> list3 = TreeUtil.buildTreeByAllStream(list);
return ResultStat.OK.wrap(list3);
}
}
构建树结构工具类(三种方式)
/**
* @ClassName TreeUtil
* @Description 构建树结构工具类
* @Author hl
* @Date 2022/9/28 15:13
* @Version 1.0
*/
public class TreeUtil {
/**
* Stream流升级构建
* @param trees
* @return
*/
public static List<TreeSelect> buildTreeByAllStream(List<TreeSelect> trees){
return trees.stream().filter(m -> m.getParentId() == 0).peek(
(m) -> m.setChildren(getChildrenList(m, trees))
kxtjl ).collect(Collectors.toList());
}
/**
* 获取子节点列表
* @param tree
* @param list
* @return
*/
public static List<TreeSelect> getChildrenList(TreeSelect tree, List<TreeSelect> list){
return list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).peek(
(item) -> item.setChildren(getChildrenList(item, list))
编程 ).collect(Collectors.toList());
}
/**
* 利用Java 8 Stream流进行处理(原理还是递归)
* @param trees
* @return
*/
public static List<TreeSelect> buildTreeByStream(List<TreeSelect> trees){
//获取parentId = 0的根节点
List<TreeSelect> list = trees.stream().filter(item -> item.getParentId() == 0L).collect(Collectors.toList());
//根据parentId进行分组
Map<Long, List<TreeSelect>> map = trees.stream().collect(Collectors.groupingBy(TreeSelect::getParentId));
recursionFnTree(list, map);
return list;
}
/**
* 递归遍历节点
* @param list
* @param map
*/
public static void recursionFnTree(List<TreeSelect> list, Map<Long, List<TreeSelect>> map){
for (TreeSelect treeSelect : list) {
List<TreeSelect> childList = map.get(treeSelect.getId());
treeSelect.setChildren(childList);
if (null != childList && 0 < childList.size()){
recursionFnTree(childList,map);
}
}
}
/**
* 构建前端所需要树结构
*
* @param trees 列表
* @return 树结构列表
*/
public static List<TreeSelect> buildTree(List<TreeSelect> trees) {
List<TreeSelect> returnList = new ArrayList<>();
List<Long> tempList = new ArrayList<>();
for (TreeSelect tree : trees) {
tempList.add(tree.getId());
}
for (TreeSelect treeSelect : trees) {
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(treeSelect.getParentId())) {
recursionFn(trees, treeSelect);
returnList.add(treeSelect);
}
}
if (returnList.isEmpty()) {
returnList = trees;
}
return returnList;
}
/**
* 递归列表
*/
private static void recursionFn(List<TreeSelect> list, TreeSelect t) {
// 得到子节点列表
List<TreeSelect> childList = getChildList(list, t);
t.setChildren(childList);
for (TreeSelect tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
/**
* 得到子节点列表
*/
private static List<TreeSelect> getChildList(List<TreeSelect> list, TreeSelect t) {
List<TreeSelect> tlist = new ArrayList<>();
for (TreeSelect n : list) {
if (ObjectUtil.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
tlist.add(n);
}
}
return tlist;
}
/**
* 判断是否有子节点
*/
private static boolean hasChild(List<TreeSelect> list, TreeSelect t) {
return getChildList(list, t).size() > 0;
}
static class TreeSelect implements Serializable {
/** 节点ID */
private Long id;
js /** 节点名称 */
private String label;
/** 父ID */
private Long http://www.devze.comparentId;
/** 子节点 */
private List<TreeSelect> children;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public List<TreeSelect> getChildren() {
return children;
}
public void setChildren(List<TreeSelect> children) {
this.children = children;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
}
}
执行结果

总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
加载中,请稍侯......
精彩评论