美文网首页
java 创建树形结构遍历

java 创建树形结构遍历

作者: 10676 | 来源:发表于2022-08-23 14:25 被阅读0次

可能平常会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理。

我们一起来看看,代码实现为了实现简单,就模拟查看数据库所有数据到List里面。

实体类:Menu.java
/**
 * @Description: car_sort
 * @Author: jeecg-boot
 * @Date:   2022-08-23
 * @Version: V1.0
 */
@Data
@TableName("car_sort")
@ApiModel(value="car_sort对象", description="car_sort")
public
class Menu   implements Serializable {
    public Integer id;
    public String name;
    public Integer parentId;
    public List<Menu> childList;

    public Menu(Integer id, String name, Integer parentId) {
        this.id = id;
        this.name = name;
        this.parentId = parentId;
    }

}
方式一:使用stream 流
/**
 * 构造数据
 * @return
 */
public List<Menu> getMenuData() {
    List<Menu> menus = Lists.newArrayList();
    menus.add(new Menu(1, "根节点", 0));
    menus.add(new Menu(2, "子节点-1", 1));
    menus.add(new Menu(3, "节点-1.1", 2));
    menus.add(new Menu(4, "子节点-1.2", 2));
    menus.add(new Menu(5, "根节点-1.3", 2));
    menus.add(new Menu(6, "根节点-2", 1));
    menus.add(new Menu(7, "根节点-2.1", 6));
    menus.add(new Menu(8, "根节点-2.2", 6));
    menus.add(new Menu(9, "根节点-2.2.1", 7));
    menus.add(new Menu(10, "根节点-2.2.2", 7));
    menus.add(new Menu(11, "根节点-3", 1));
    menus.add(new Menu(12, "根节点-3.1", 11));
    menus.add(new Menu(13, "根节点-3.2", 11));
    menus.add(new Menu(14, "根节点-3.2.1", 13));
    return menus;
}

@Test
public void testMenuTree() {
    List<Menu> menuDatas = getMenuData();
    List<Menu> menuTree = menuDatas.stream().filter(m -> m.getParentId() == 0)
            .map((m) -> {
                        m.setChildList(getChildrens(m, menuDatas));
                        return m;
                    }
            ).collect(Collectors.toList());
    System.out.println("菜单树结构:" + JsonUtil.toJson(menuTree));
}


/**
 * 获取子类
 * @param parent
 * @param menuDatas
 * @return
 */
private List<Menu> getChildrens(Menu parent, List<Menu> menuDatas) {
    List<Menu> childList = menuDatas.stream().filter(m -> {
        return Objects.equals(m.getParentId(), parent.getId());
    }).map((m) -> {
        m.setChildList(getChildrens(m, menuDatas));
        return m;
    }).collect(Collectors.toList());
    return childList;
}
运行结果
方式二:使用原生的循环递归操作,这里使用iterator循环,设置完数据后移除,可以减少循环数据。
@Test
public void testMenu() {
    List<Menu> menuDatas = getMenuData();

    List<Menu> returnList = Lists.newArrayList();
    for (Iterator<Menu> lt = menuDatas.iterator(); lt.hasNext(); ) {
        Menu menu = lt.next();
        if (menu.getParentId() == 0) {
            returnList.add(menu);
            lt.remove();
        }
    }

    returnList.forEach(r -> {
        r.setChildList(getChild(r.getId(), menuDatas));
    });

    System.out.println("菜单树结构:" + JsonUtil.toJson(returnList));
}

private static List<Menu> getChild(Integer parentId, List<Menu> menuList) {
    List<Menu> childList = Lists.newArrayList();
    for (Iterator<Menu> lt = menuList.iterator(); lt.hasNext();){
        Menu menu = lt.next();
        if (parentId.equals(menu.getParentId())) {
            childList.add(menu);
            lt.remove();
        }
    }

    for (Menu menu : childList) {
        List<Menu> child = getChild(menu.getId(), menuList);
        menu.setChildList(child);
    }
    return childList;
}

实例:

我得改造:
    @Override
    public List<CarSort> getTree() {
        LambdaQueryWrapper<CarSort> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(CarSort::getDeleteFlag,0);
        queryWrapper.orderByAsc(CarSort::getTitle);
//        QueryWrapper<CarSort> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("delete_flag",0);
//        queryWrapper.orderByAsc("CONVERT( title USING gbk )");
        List<CarSort> list = carSortService.list(queryWrapper);
//        List<CarSort> list = baseMapper.getTree();

        List<CarSort> carSortTreeList = Lists.newArrayList();
        for (Iterator<CarSort> lt = list.iterator(); lt.hasNext(); ) {
            CarSort carSort = lt.next();
            if (carSort.getPid().equals("0")) {
                carSortTreeList.add(carSort);
                lt.remove();
            }
        }

        carSortTreeList.forEach(r -> {
            r.setItem(getTreeChild(r.getId(), list));
        });

        return carSortTreeList;

    }

    private static List<CarSort> getTreeChild(String parentId, List<CarSort> menuList) {
        List<CarSort> childList = Lists.newArrayList();
        for (Iterator<CarSort> lt = menuList.iterator(); lt.hasNext();){
            CarSort carSort = lt.next();
            if (parentId.equals(carSort.getPid())) {
                childList.add(carSort);
                lt.remove();
            }
        }

        for (CarSort carSort : childList) {
            List<CarSort> child = getTreeChild(carSort.getId(), menuList);
            carSort.setItem(child);
        }
        return childList;
    }
我得建表语句及部分数据

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `car_sort`
-- ----------------------------
DROP TABLE IF EXISTS `car_sort`;
CREATE TABLE `car_sort` (
  `id` varchar(36) NOT NULL COMMENT 'id',
  `title` varchar(100) DEFAULT NULL COMMENT 'title',
  `Delete` bit(1) NOT NULL DEFAULT b'0',
  `fid` varchar(36) DEFAULT NULL COMMENT 'fid',
  `enable` varchar(1) NOT NULL COMMENT '可用',
  `creattime` datetime NOT NULL COMMENT 'creattime',
  `Img` varchar(100) DEFAULT NULL COMMENT '图片',
  `delete_flag` varchar(1) NOT NULL COMMENT 'delete_flag',
  `pid` varchar(36) DEFAULT NULL COMMENT '父级节点',
  `has_child` varchar(3) DEFAULT NULL COMMENT '是否有子节点',
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

结果数据还是挺满意的
![image.png](https://img.haomeiwen.com/i20688241/6e5157cf9763a116.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

相关文章

  • java 创建树形结构遍历

    可能平常会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可...

  • Java 遍历之树形菜单

    如图,实现这样一个树形结构的菜单,java怎么实现?这里就需要用到遍历。 新建一个实体类 树形结构 思路:首先找根...

  • Java 树形结构构造器

    Java 树形结构构造器 1. 创建树型结构节点基类 2. 树型结构构造器 先生成父节点然后调用buildChil...

  • 递归遍历树形结构

    原有的结构 (树形结构) 实现后的结构 完整代码 可复制代码 Document...

  • 树形组件拖拽写法思路

    树形结构的生成,可以通过递归树形数据遍历而成 节点的思路 children-container 需要加个paddi...

  • 10.组合模式(结构型)

    组合模式(结构型) 一、概述 对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也...

  • JS树结构数据的遍历

    title: JS树结构数据的遍历date: 2022-04-14description: 针对项目中出现树形结构...

  • java 树形结构

    树实体类 树结构排序工具类 测试类 输出结果

  • 树形结构创建_画线

    树型结构 待整理

  • 2018-03-26

    组合模式_a概述 对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方...

网友评论

      本文标题:java 创建树形结构遍历

      本文链接:https://www.haomeiwen.com/subject/gkrggrtx.html