java 递归返回树形组织结构(附带树形菜单的搜索)

简介: java 递归返回树形组织结构(附带树形菜单的搜索)

表结构

create table Project 
(
ID NUMBER not null,
NAME VARCHAR2(50),
PID NUMBER //父节点
)

实体

public class Project implements Serializable {
    private String Id;
    private String pId;
    private List<Project> childrenProjectList;
}

从一级往下递归组树

以下是Sqlserver的递归sql,mysql的话可以对应去查,原理是一样的,就是用sql查出所有树节点,然后存入hashmap(以pid为key,list为value),然后从一级项目去map里取,如果不想用递归sql,如果数据不多可以直接查出所有数据放入hashmap,如果数据多可以在java代码里循环查询数据库找出所有的节点(不推荐,频繁查库)

查询符合条件的数据和子节点

with subqry(Id,projectname,pid) as (
select id,projectname,pid from Project where ProjectManager = 'gehui'
union all
select Project.id,Project.projectname,Project.pid from Project,subqry
where Project.pid = subqry.id
)
select * from subqry;

查询符合条件的数据和父节点

with maco as
(
select * from Project where ProjectManager = 'gehui'
union all
select t.* from Project t,maco m where t.Id=m.pid
)
select * from maco order by ProjectManager

获取树节点

  projectSonList = projectMapper.selectSonProject(query);
            projectFatherList = projectMapper.selectFatherProject(query);
            projectFatherList.addAll(projectSonList);
            projectAllList = projectFatherList.stream().distinct().collect(Collectors.toList());

将节点放入hashmap

HashMap<String, List<Project>> ProjectMap= getProjectPidMap(projectAllList);
/**
     * 生成id为key的map
     *
     * @param projectFatherList
     * @return
     */
    public HashMap<String, List<Project>> getProjectIdMap(List<Project> projectFatherList) {
        HashMap<String, List<Project>> allProjectIdMap = new HashMap<>();
        //把所有的项目进行处理,用hashmap存储,以id为key,实体为value
        if (projectFatherList.size() != 0) {
            for (Project project : projectFatherList
            ) {
                // map中没有,并且不是父id不为空
                if (project.getId() != null) {
                    if (allProjectIdMap.get(project.getId()) == null) {
                        List<Project> projectLists = new ArrayList<>();
                        projectLists.add(project);
                        allProjectIdMap.put(project.getId(), projectLists);
                    } else {
                        allProjectIdMap.get(project.getId()).add(project);
                    }
                }
            }
        }
        return allProjectIdMap;
    }
  /**
     * 生成pid为key的map
     *
     * @param projectFatherList
     * @return
     */
    public HashMap<String, List<Project>> getProjectPidMap(List<Project> projectFatherList) {
        HashMap<String, List<Project>> allProjectIdMap = new HashMap<>();
        //把所有的项目进行处理,用hashmap存储,以id为key,实体为value
        if (projectFatherList.size() != 0) {
            for (Project project : projectFatherList
            ) {
                // map中没有,并且不是父id不为空
                if (project.getpId() != null) {
                    if (allProjectIdMap.get(project.getpId()) == null) {
                        List<Project> projectLists = new ArrayList<>();
                        projectLists.add(project);
                        allProjectIdMap.put(project.getpId(), projectLists);
                    } else {
                        allProjectIdMap.get(project.getpId()).add(project);
                    }
                }
            }
        }
        return allProjectIdMap;
    }

开始组树

 /**
     * 从一级向下递归
     *
     * @param projectFatherList
     * @return
     */
    public List<Project> getProjectTree(List<Project> projectFatherList, HashMap<String, List<Project>> allProjectMap) {
        //遍历,拿出所有的pidw为零的项目
        List<Project> firstLeaveProject = projectFatherList.stream().filter(project -> StringUtils.isEmpty(project.getpId())).collect(Collectors.toList());
        projectFatherList = getAllBottomProject(firstLeaveProject, allProjectMap);
        return projectFatherList;
    }

递归向下

 /**
     * 递归遍历此项目下所有项目
     *
     * @param leaveProjectList
     * @return
     */
    public List<Project> getAllBottomProject(List<Project> leaveProjectList, HashMap<String, List<Project>> allProjectMap) {
        if (leaveProjectList != null && leaveProjectList.size() != 0 && !allProjectMap.isEmpty()) {
            for (int i = leaveProjectList.size() - 1; i >= 0; i--) {
                if (leaveProjectList.get(i).getId() != null && allProjectMap.get(leaveProjectList.get(i).getId()) != null) {
                    leaveProjectList.get(i).setChildrenProjectList(allProjectMap.get(leaveProjectList.get(i).getId()));
                    //递归调用,查看子集是否还有子集
                    getAllBottomProject(leaveProjectList.get(i).getChildrenProjectList(), allProjectMap);
                }
            }
        }
        return leaveProjectList;
    }

树形菜单的搜索

根据筛选条件递归向上建树

/**
     * 递归向上建树
     *
     * @param leaveProjectList
     * @return
     */
    public List<Project> getAllProject(List<Project> leaveProjectList, List<Project> projectAllList, List<Project> projectLeaveFatherList) throws IOException, ClassNotFoundException {

        if (leaveProjectList != null && leaveProjectList.size() != 0) {
            for (Project project : leaveProjectList
            ) {
                List<Project> projectTempList = new LinkedList<>();
                List<Project> leaveProjectFatherList = new LinkedList<>();
                List<Project> leaveEqualsProject = new LinkedList<>();
                // 为每个元素找到父级树
                leaveProjectFatherList = projectAllList.stream().filter(e -> e.getId().equals(project.getpId())).collect(Collectors.toList());
                if (leaveProjectFatherList.size() > 0) {
                    // 把该元素放到父级树的子集树元素集中
                    leaveProjectFatherList.get(0).setChildrenProjectList(leaveEqualsProject);
                    leaveProjectFatherList.get(0).getChildrenProjectList().add(project);
                    leaveProjectFatherList.get(0).setHigh(project.getHigh() + Constant.ONE);
                    if (leaveProjectFatherList.get(0).getpId() != null) {
                        leaveProjectFatherList = getProject(leaveProjectFatherList, projectAllList);
                    }
                    if (leaveProjectFatherList.get(0) != null && leaveProjectFatherList.get(0).getpId() == null) {
                        projectLeaveFatherList.addAll(deepCopy(leaveProjectFatherList));
                    }
                } else {
                    projectTempList.add(project);
                    projectLeaveFatherList.addAll(deepCopy(projectTempList));
                }


            }

        }
        return projectLeaveFatherList;
    }

    public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);

        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream in = new ObjectInputStream(byteIn);
        @SuppressWarnings("unchecked")
        List<T> dest = (List<T>) in.readObject();
        return dest;
    }


    public List<Project> getProject(List<Project> leaveProjectList, List<Project> projectAllList) {
        List<Project> leaveProjectFather;
        List<Project> leaveEquals = new LinkedList<>();
        if (leaveProjectList != null && leaveProjectList.size() != 0) {
            for (Project project : leaveProjectList
            ) {
                // 为每个元素找到父级树
                leaveProjectFather = projectAllList.stream().filter(e -> e.getId().equals(project.getpId())).collect(Collectors.toList());
                if (leaveProjectFather.size() > 0) {
                    // 把该元素放到父级树的子集树元素集中
                    leaveProjectFather.get(0).setChildrenProjectList(leaveEquals);
                    leaveProjectFather.get(0).getChildrenProjectList().add(project);
                    leaveProjectFather.get(0).setHigh(project.getHigh() + Constant.ONE);
                    leaveProjectList = leaveProjectFather;
                    leaveProjectList = getProject(leaveProjectList, projectAllList);
                }
            }
        }
        return leaveProjectList;
    }

总结

其实小编最喜欢的还是需要哪层返回哪层的数据,这样不需要递归,比如初始化只显示一级菜单,那么只返回一级菜单即可,点击再返回下一层

目录
相关文章
|
4天前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
16 4
|
1天前
|
Java
蓝桥杯Java组暴力递归搜图
蓝桥杯Java组暴力递归搜图
12 4
|
4天前
|
算法 Java 机器人
Java数据结构与算法:AVL树
Java数据结构与算法:AVL树
|
1天前
|
Java
2021蓝桥杯大赛软件类国赛Java大学B组 完全日期 复杂遍历搜索
2021蓝桥杯大赛软件类国赛Java大学B组 完全日期 复杂遍历搜索
10 2
|
4天前
|
存储 算法 Java
Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。
【6月更文挑战第21天】Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。简单哈希表实现未涵盖冲突解决和删除操作。
13 1
|
11天前
|
存储 安全 Java
深入解析Java HashMap的高性能扩容机制与树化优化
深入解析Java HashMap的高性能扩容机制与树化优化
11 1
|
11天前
|
算法 前端开发 Java
探讨Java中递归构建树形结构的算法
探讨Java中递归构建树形结构的算法
9 1
|
1天前
|
Java
java使用递归遍历文件目录
java使用递归遍历文件目录
5 0
|
1天前
|
Java
Java 中的分支结构
Java 中的分支结构
3 0
|
1天前
|
存储 前端开发 算法
2016届蓝桥杯大赛软件类国赛Java大学B组 反幻方 暴力搜索
2016届蓝桥杯大赛软件类国赛Java大学B组 反幻方 暴力搜索
3 0