可能平常会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父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)
网友评论