Java树形结构 根据父节点获取最底层节点数据 树形xml

目录

1 项目结构

2 使用的相关jar包

3 相关代码

3.1 实体类

3.2 相关工具类

3.2.1 将对象转化为map的工具类

3.2.2 Xml创建工具类 

3.3 功能实现 

 3.3.1 Java通过递归获得树形结构

3.3.2 根据父节点获取最底层节点

3.3.3 树形xml


1 项目结构

这里做测试,写的不标准。。。。。。

2 使用的相关jar包

(让Java甜甜的) hutool-allcommons-beanutilslombok、(Document) dom4j 四个关键架包。

        部分 pom.xml 如下:


        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>
       
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.5</version>
        </dependency>
      
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

 话不多说,上代码。。。。。

3 相关代码

3.1 实体类

Dept.java

/**
 * @author W
 * @createDate 2022/8/10
 * @description: Dept实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
    private String id;
    private String name;
    private String parentId;
    private List<Dept> children = new ArrayList<>();
}

3.2 相关工具类

3.2.1 将对象转化为map的工具类

ObjectConvertToMapUtil.java 

/**
 * @author W
 * @createDate 2022/8/10
 * @description: 对象转化为Map
 */
public class ObjectConvertToMapUtil {
    private static final Logger logger = LoggerFactory.getLogger(ObjectConvertToMapUtil.class);

    public static Map<String,String> objConvertToMap(Object obj){
        Map<String,String> retMap = new TreeMap<String, String>();
        try {
            if(obj != null){
                Map<?,?> map = BeanUtils.describe(obj);
                String name = null;
                Object value = null;
                for(Object key : map.keySet()){
                    if(key != null ){
                        name = String.valueOf(key);
                        if(!name.equals("class")){
                            value = map.get(key);
                            retMap.put(name, value == null ? "" : String.valueOf(value));
                        }
                    }
                }
            }
        } catch (IllegalAccessException e) {
            logger.error(e.getMessage());
        } catch (InvocationTargetException e) {
            logger.error(e.getMessage());
        } catch (NoSuchMethodException e) {
            logger.error(e.getMessage());
        }
        return retMap;
    }
}

3.2.2 Xml创建工具类 

XmlUtil.java

/**
 * @author W
 * @createDate 2022/8/10
 * @description:
 */
public class XmlUtil {
    /**
     * 在指定的节点下创建一个节点
     * @param parent  父节点
     * @param name    要创建的节点名称
     * @return
     */
    public static Element createChildElement(Element parent, String name) {
        return createChildElement(parent,name,null,null);
    }

    /**
     * 在指定的节点下创建一个节点
     * @param parent  父节点
     * @param name    要创建的节点名称
     * @param text    要創建的节点文本
     * @return
     */
    public static Element createChildElement(Element parent, String name, String text) {
        return createChildElement(parent,name,text,null);
    }

    /**
     * 在指定的节点下创建一个节点,并且创建所有给定的属性,如果给定的属性集为空或不包含属性信息,将不创建属性
     * @param parent  父节点
     * @param name    要创建的节点名称
     * @param attrMap 要创建的节点属性
     * @return
     */
    public static Element createChildElement(Element parent, String name,Map<String,String> attrMap) {
        return createChildElement(parent,name,null,attrMap);
    }

    /**
     * 在指定的节点下创建一个节点,并且创建所有给定的属性,如果给定的属性集为空或不包含属性信息,将不创建属性
     * @param parent  父节点
     * @param name    要创建的节点名称
     * @param text    要創建的节点文本
     * @param attrMap 要创建的节点属性
     * @return
     */
    public static Element createChildElement(Element parent, String name, String text, Map<String,String> attrMap) {
        Element child = parent.addElement(name);
        if(StrUtil.isNotBlank(text)){
            child.setText(text);
        }
        if(attrMap != null && attrMap.size() > 0){
            for(String key : attrMap.keySet()){
                child.addAttribute(key, attrMap.get(key));
            }
        }
        return child;
    }
}

3.3 功能实现 

         构造数据

public static List<Dept> getDeptAll(){
        Dept dept = new Dept("1","一层","0",null);

        Dept dept1 = new Dept("2","二层1","1",null);
        Dept dept2 = new Dept("3","二层2","1",null);

        Dept dept3 = new Dept("21","三层1","2",null);
        Dept dept4 = new Dept("22","三层2","2",null);
        Dept dept5 = new Dept("31","三层3","3",null);
        Dept dept6 = new Dept("32","三层4","3",null);

        Dept dept7 = new Dept("211","四层1","21",null);
        Dept dept8 = new Dept("212","四层2","21",null);
        Dept dept9 = new Dept("221","四层3","22",null);
        Dept dept10 = new Dept("222","四层4","22",null);
        Dept dept11 = new Dept("311","四层5","31",null);
        Dept dept12 = new Dept("312","四层6","31",null);
        Dept dept13 = new Dept("321","四层7","32",null);
        Dept dept14 = new Dept("322","四层8","32",null);

        Dept dept15 = new Dept("A","一层","0",null);

        Dept dept16 = new Dept("B","二层1","A",null);
        Dept dept17 = new Dept("C","二层2","A",null);

        Dept dept18 = new Dept("BA","三层1","B",null);
        Dept dept19 = new Dept("BB","三层2","B",null);
        Dept dept20 = new Dept("CA","三层3","C",null);
        Dept dept21 = new Dept("CB","三层4","C",null);

        List<Dept> deptList = new ArrayList<>();
        deptList.add(dept);
        deptList.add(dept1);
        deptList.add(dept2);
        deptList.add(dept3);
        deptList.add(dept4);
        deptList.add(dept5);
        deptList.add(dept6);
        deptList.add(dept7);
        deptList.add(dept8);
        deptList.add(dept9);
        deptList.add(dept10);
        deptList.add(dept11);
        deptList.add(dept12);
        deptList.add(dept13);
        deptList.add(dept14);
        deptList.add(dept15);
        deptList.add(dept16);
        deptList.add(dept17);
        deptList.add(dept18);
        deptList.add(dept19);
        deptList.add(dept20);
        deptList.add(dept21);
       return deptList;
    }

        数据结构图,如下

 3.3.1 Java通过递归获得树形结构

  • 实现方法
 /**
    *
    * @param deptAll 所有的集合
    * @param deptRoots 所有根节点的集合
 */
public static void getDeptTree(List<Dept> deptAll,List<Dept> deptRoots){
    if(CollectionUtil.isNotEmpty(deptRoots)){
        for (Dept root : deptRoots) {
            List<Dept> children = deptAll.stream().filter(item -> item.getParentId().equals(root.getId())).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(children)){
                 root.setChildren(children);
                 getDeptTree(deptAll,children);
            }
        }
    }
}
  • 测试方法
@GetMapping("/getTree")
public ResponseResult getTree(){
    List<Dept> deptAll = GetLeafNode.getDeptAll();
    List<Dept> deptRoots = deptAll.stream().filter(item -> "0".equals(item.getParentId())).collect(Collectors.toList());
    GetLeafNode.getDeptTree(deptAll,deptRoots);
    return ResponseResult.success("树形结构",deptRoots);
}
  • 测试结果

3.3.2 根据父节点获取最底层节点

  •  实现方法
/**
   * 获取叶子节点
   * @param deptMap 所有的元素集合(根据父级ID进行了分组)
   * @param parentId 父 id
   * @param toLowerChildrenSet 存放叶子节点的集合
   * @return
*/
public static Set<Dept> getMinimumChildren(Map<String, List<Dept>> deptMap,String parentId,Set<Dept> toLowerChildrenSet){
    // 存放parentId下所有的子节点
    Set<Dept> result = new HashSet<>();
    // 获取当前父节点下所有的子节点
    List<Dept> deptNodes = deptMap.get(parentId);
    if(CollectionUtil.isEmpty(deptNodes)){
         return null;
    }
    for (Dept dept : deptNodes) {
         Set<Dept> lowerChildrenSet = getMinimumChildren(deptMap, dept.getId(), result);
         if(CollectionUtil.isEmpty(lowerChildrenSet)){
             // 如果返回null,表示当前遍历的dept节点为最底层的节点
             result.add(dept);
         }
    }
    // 将当前获取的根节存放到上一个父id对应的根节点集合
    toLowerChildrenSet.addAll(result);
    return result;
}
  • 测试方法
@GetMapping("/getNodes")
public ResponseResult getNodes(){
    List<Dept> deptAll = GetLeafNode.getDeptAll();
    // 1.获得最底层子节点数据,即叶子节点
    Set<Dept> toLowerChildren = new HashSet<>();
    // 按照父节点分组
    Map<String, List<Dept>> deptMap = deptAll.stream().collect(Collectors.groupingBy(Dept::getParentId));
    // 获取parentId="0"的所有子节点
    List<Dept> depts = deptMap.get("0");
    for (Dept dept : depts) {
         if(CollectionUtil.isNotEmpty(deptMap.get(dept.getId()))){
             GetLeafNode.getMinimumChildren(deptMap,dept.getId(),toLowerChildren);
         }else {
             toLowerChildren.add(dept);
         }
   }
   return ResponseResult.success("根据父节点获得最底层节点",toLowerChildren);
}
  • 测试结果

3.3.3 树形xml

  • 实现方法
/**
 * 获取树形的xmlDoc
 * @param tree
 * @param deptRoots 树形集合
 */
public static void getTreeXmlDoc(Element tree,List<Dept> deptRoots){
    if(CollectionUtil.isNotEmpty(deptRoots)){
        for (Dept deptRoot : deptRoots) {
            Map<String, String> deptMap = ObjectConvertToMapUtil.objConvertToMap(deptRoot);
            deptMap.remove("children");
            Element nodeParent = XmlUtil.createChildElement(tree, "dept", deptMap);
            if(CollectionUtil.isNotEmpty(deptRoot.getChildren())){
                getTreeXmlDoc(nodeParent,deptRoot.getChildren());
            }
        }

     }
}
  • 测试方法
@GetMapping("/getTreeXml")
public ResponseResult getTreeXml(){
    List<Dept> deptAll = GetLeafNode.getDeptAll();
    List<Dept> deptRoots = deptAll.stream().filter(item -> "0".equals(item.getParentId())).collect(Collectors.toList());
    // 2.获得树形结构
    GetLeafNode.getDeptTree(deptAll,deptRoots);
    Document xmlDOC = DocumentHelper.createDocument();
    Element root = xmlDOC.addElement("root");
    Element tree = XmlUtil.createChildElement(root, "tree");
    GetLeafNode.getTreeXmlDoc(tree,deptRoots);
    return ResponseResult.success("树形xml",xmlDOC.asXML());
}
  • 测试结果

猜你喜欢

转载自blog.csdn.net/weixin_48568302/article/details/126273963