public Result getBmsMenuList(UserSessionVO userSessionInfo) {
        // 查询顶级节点菜单
        List<BmsMenuVO> bmsMenuVOList = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO());
        for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
            getBmsMenuListByRecursion(bmsMenuVO);
        return Result.createWithModels(null, bmsMenuVOList);
 private void getBmsMenuListByRecursion(BmsMenuVO bmsMenuVO) {
        List<BmsMenuVO> bmsMenuVOS = bmsMenuDao.selectBmsMenuList(new BmsMenuQueryConditionVO().setParentId(bmsMenuVO.getId()));
        if (CollectionUtils.isEmpty(bmsMenuVOS)) {
            return;
        bmsMenuVO.setChildBmsMenuList(bmsMenuVOS);
        for (BmsMenuVO menuVO : bmsMenuVOS) {
            getBmsMenuListByRecursion(menuVO);

2.双层for

// 查询主节点
List<BmsMenuVO> bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);
// 拼装结果
 List<BmsMenuVO> bmsMenuTree = new ArrayList<>();
 for (BmsMenuVO bmsMenuVO : bmsMenuVOList) {
      // 根节点的父Id为null
      if (bmsMenuVO.getParentId() == null) {
                bmsMenuTree.add(bmsMenuVO);
      for (BmsMenuVO menuVO : bmsMenuVOList) {
           if (menuVO.getParentId() != null && menuVO.getParentId().equals(bmsMenuVO.getId())) {
               if (CollectionUtils.isEmpty(bmsMenuVO.getChildBmsMenuList())) {
                        bmsMenuVO.setChildBmsMenuList(new ArrayList<>());
                bmsMenuVO.getChildBmsMenuList().add(menuVO);
  // 返回结果
 return Result.createWithModels(null, bmsMenuTree);

3.map遍历

 // 查询所有节点
 List<BmsMenuVO> bmsMenuVOList = bmsRoleMenuDao.getAllRoleMenuList(condition);
 // 拼装结果     
 List<BmsMenuVO> bmsMenuTree = new ArrayList<>();
 // 用来存储节点的子元素map
 Map<Long, BmsMenuVO> childBmsMenuMap = new LinkedHashMap<>();
        for (BmsMenuVO menuVO : bmsMenuVOList) {
            childBmsMenuMap.put(menuVO.getId(), menuVO);
        for (Long bmsMenuId : childBmsMenuMap.keySet()) {
            BmsMenuVO menuVO = childBmsMenuMap.get(bmsMenuId);
            Long parentId = menuVO.getParentId();
            if (parentId == null) {
                bmsMenuTree.add(menuVO);
            } else {
                BmsMenuVO parentMenuVO = childBmsMenuMap.get(parentId);
                if (parentMenuVO.getChildBmsMenuList() == null) {
                    parentMenuVO.setChildBmsMenuList(new ArrayList<>());
                parentMenuVO.getChildBmsMenuList().add(menuVO);

总结上述代码,复杂度从上到下依次降低,最后用map只要两次循环,所以以后树结构可以不用递归

一般我们存储树形数据,如菜单等等存在子父级关系的,会使用每条数据都存储父节点id的方法。 最近接触到一个更好的方法,一般数据的每条唯一主键较长,且只存储父节点id,要找到祖父节点等更高的节点,会需要重复遍历,找起来相对麻烦。 我们可以对每条数据都加几个字段,一个为层级,从1开始,每下一个节点递增1,一个为行次,每个层级均从1开始,同层级每一条数据递增1。 总体思路:利用Java8的新特性Lambda和流的map、collect,不断的递归调用得到树形结构另:如果想得到无限层的话,把level的限制放开,构造并返回自定义的数据结构就可以了代码如下public ItemCatResult queryItemCatsNew() {//声明一个存储的对象,然后构建对象ItemCatResult result=new ItemCatResult();List... import apple.laf.JRSUIUtils; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java 【【左子树的中序遍历结果】,根节点,【右子树的中序遍历结果】】 只要我们在中序遍历中定位到根节点,那么我们就可以分别知道左子树和右子树中的节点数目。由于同一颗子树的前序遍历和中序遍历的长度显然是相同的,因此我们就可以对应到前序遍历的结果中,对上述形式中的所有左右括