构建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)。
精彩评论