可能平常会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来,然后通过流式处理。
我们一起来看看,代码实现为了实现简单,就模拟查看数据库所有数据到List里面。
实体类:Menu.java
/**
* 菜单类
*/
@Data
public class Menu {
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;
}