java使用递归实现Tree数据组装
程序员文章站
2022-05-08 19:12:50
...
基于hutool工具中的方法封装,特此记录一下。
/**
* 行数据转tree结构数据工具类,核心采用hutool提供的api,进行了简单封装
* @author lpt
* @date 2020/11/24
*/
public class BuildTreeUtil {
/* 默认根级 */
static final String defaultLevel = StrUtil.isNotEmpty(CommonConstant.TREE_DEFAULT_LEVEL) ? CommonConstant.TREE_DEFAULT_LEVEL : "0";
/**
* desc 构建树型数据主方法,采用默认配置项,默认从根级取
* @param nodeList
* @return
*/
public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList){
return buildTree(nodeList, null, defaultLevel, getDefaultConfig());
}
/**
* 构建树型数据主方法,有扩展字段,采用默认配置项,默认从根级取
* @param nodeList
* @param extKeyArr
* @return
*/
public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList, String[] extKeyArr){
return buildTree(nodeList, extKeyArr, defaultLevel, getDefaultConfig());
}
/**
* desc 构建树型数据主方法,采用默认配置项,指定层级
* @param nodeList
* @param parentId
* @return
*/
public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList, String[] extKeyArr, String parentId){
return buildTree(nodeList, extKeyArr, parentId, getDefaultConfig());
}
/**
* desc 构建树型数据主方法,采用自定义返回key配置项
* @param nodeList
* @param parentId
* @param treeNodeConfig
* @return
*/
public static List<Tree<Object>> buildTree(List<TreeNode<Object>> nodeList, String[] extKeyArr, String parentId, TreeNodeConfig treeNodeConfig){
if(extKeyArr != null && extKeyArr.length > 0){
//如果有扩展字段在此处处理
nodeList.forEach((node)->{
Map<String, Object> map = BeanUtil.beanToMap(node);
node.setExtra(BuildTreeUtil.setExtra(map, extKeyArr));
});
}
if(CollUtil.isNotEmpty(nodeList) && StrUtil.isNotEmpty(parentId)){
if(null == treeNodeConfig){
return TreeUtil.build(nodeList, parentId);
}else {
//转换器
return TreeUtil.build(nodeList, parentId, treeNodeConfig,
(treeNode, tree) -> {
tree.setId(treeNode.getId());
tree.setParentId(treeNode.getParentId());
tree.setWeight(treeNode.getWeight());
tree.setName(treeNode.getName());
// 扩展属性填充
if(CollUtil.isNotEmpty(treeNode.getExtra())){
treeNode.getExtra().forEach((key, value)->{
tree.putExtra(key, value);
});
}
});
}
}
return CollUtil.newArrayList();
}
/**
* desc 获取默认配置
* @return TreeNodeConfig
*/
public static TreeNodeConfig getDefaultConfig(){
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
treeNodeConfig.setIdKey(StrUtil.isNotEmpty(CommonConstant.ID_KEY) ? CommonConstant.ID_KEY : "key");
treeNodeConfig.setNameKey(StrUtil.isNotEmpty(CommonConstant.NAME_KEY) ? CommonConstant.NAME_KEY : "title");
treeNodeConfig.setParentIdKey(StrUtil.isNotEmpty(CommonConstant.PARENT_ID_KEY) ? CommonConstant.PARENT_ID_KEY : "parentId");
treeNodeConfig.setChildrenKey(StrUtil.isNotEmpty(CommonConstant.CHILDREN_KEY) ? CommonConstant.CHILDREN_KEY : "children");
treeNodeConfig.setWeightKey(StrUtil.isNotEmpty(CommonConstant.ORDER_KEY) ? CommonConstant.ORDER_KEY : "order");
return treeNodeConfig;
}
/**
* 设置扩展字段的值
* @param map
* @param extKeyList
* @return
*/
private static Map setExtra(Map<String, Object> map, String[] extKeyList){
Map<String, Object> resultMap = CollUtil.newHashMap();
List<String> list = CollUtil.toList(extKeyList);
if(CollUtil.isNotEmpty(map) && CollUtil.isNotEmpty(list)){
list.forEach((key) -> {
resultMap.put(key, map.get(key));
});
}
return resultMap;
}
public static void main(String[] args) {
// 构建node列表
// 实用时从数据库查询返回实体类用TreeNode(hutool中封装树结构的类,sql中as的key需要和该类中的属性名对应上)
// 例:select t.id id, t.parent_id parentId, t.title name,t.order weight t from u_menu_t t
List<TreeNode<Object>> nodeList = CollUtil.newArrayList();
nodeList.add(new FunctionList("1", "0", "系统管理", 5, "menu1", "/url/page1", "desc", 1,3));
nodeList.add(new FunctionList("11", "1", "用户1管理", 2, "menu2", "/url/page1", "desc", 1,3));
nodeList.add(new FunctionList("12", "1", "用户2管理", 1, "menu3", "/url/page1", "desc", 1,3));
nodeList.add(new FunctionList("111", "11", "用户添加", 0, "menu4", "/url/page1", "desc", 1,3));
nodeList.add(new FunctionList("2", "0", "店铺管理", 1, "menu5", "/url/page1", "desc", 1,3));
nodeList.add(new FunctionList("21", "2", "商品管理", 44, "menu6", "/url/page1", "desc", 1,3));
/*模拟查询数据库结束*/
/* 扩展字段 */
System.out.println("基础字段有id、parentId、name、weight(即为hutool中TreeNode类的基础字段)");
System.out.println("带扩展字段演示");
String[] extKeyArr = {"icon", "path", "desc", "level", "type"};
List<Tree<Object>> treeList = BuildTreeUtil.buildTree(nodeList, extKeyArr);
System.out.println(treeList);
System.out.println("-----------------------------------------------------------");
System.out.println("不带扩展字段演示");
List<TreeNode<Object>> nodeList1 = CollUtil.newArrayList();
nodeList1.add(new FunctionList("1", "0", "系统管理", 5, null, null, null, null,null));
nodeList1.add(new FunctionList("11", "1", "用户1管理", 2, null, null, null, null,null));
nodeList1.add(new FunctionList("12", "1", "用户2管理", 1, null, null, null, null,null));
nodeList1.add(new FunctionList("111", "11", "用户添加", 0, null, null, null, null, null));
nodeList1.add(new FunctionList("2", "0", "店铺管理", 1 , null, null, null, null, null));
nodeList1.add(new FunctionList("21", "2", "商品管理", 44, null, null, null, null,null));
/*模拟查询数据库结束*/
List<Tree<Object>> treeList1 = BuildTreeUtil.buildTree(nodeList1);
System.out.println(treeList1);
}
}
functionList.java
/**
* 有扩展字段则加扩展字段,没有则只需继承TreeNode即可
*/
@Data
public class FunctionList extends TreeNode {
private String icon;
private String path;
private String desc;
private Integer level;
private Integer type;
/* 方便测试,可不加 */
public FunctionList(String id, String parentId, String name, Integer weight, String icon, String path, String desc, Integer level, Integer type) {
this.setId(id);
this.setName(name);
this.setParentId(parentId);
this.setWeight(weight);
this.icon = icon;
this.path = path;
this.desc = desc;
this.level = level;
this.type = type;
}
}
上一篇: 用Java组装树形List数据
下一篇: 二分查找
推荐阅读