三种方法构建Java树结构
一、准备工作
表结构
CREATE TABLE `asset_classification` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`className` varchar(50) NOT NULL COMMENT '分类名',
`status` tinyint(2) NOT NULL COMMENT '状态(0:使用中 1:停用)',
`type` tinyint(2) NOT NULL COMMENT '类别(0:设备 1:物料 2:附件)',
`writeable` tinyint(2) NOT NULL COMMENT '1:不可编辑 0:可编辑',
`parentId` int(11) NOT NULL COMMENT '父类id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=157 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT;
部分表数据

二、三种方式
- 原始递归
- 利用Java 8 Stream流进行处理(原理还是递归)
- Stream流升级构建
controller层
@RestController
public class TestController {
@Autowired
private AssetClassificationBiz assetClassificationBiz;
@GetMapping("/tree")
public HttpResponseTemp<?> getTree(){
List<AssetClassification> assetClassificationList = assetClassificationBiz.selectAll();
List<TreeUtil.TreeSelect> list = new ArrayList<>();
for (AssetClassification assetClassification : assetClassificationList) {
TreeUtil.TreeSelect treeSelect = new TreeUtil.TreeSelect();
treeSelect.setId(Convert.toLong(assetClassification.getId()));
treeSelect.setLabel(assetClassification.getClassName());
treeSelect.setParentId(Convert.toLong(assetClassification.getParentId()));
list.add(treeSelect);
}
List<TreeUtil.TreeSelect> list1 = TreeUtil.buildTree(list);
List<TreeUtil.TreeSelect> list2 = TreeUtil.buildTreeByStream(list);
List<TreeUtil.TreeSelect> list3 = TreeUtil.buildTreeByAllStream(list);
return ResultStat.OK.wrap(list3);
}
}
构建树结构工具类(三种方式)
public class TreeUtil {
public static List<TreeSelect> buildTreeByAllStream(List<TreeSelect> trees){
return trees.stream().filter(m -> m.getParentId() == 0).peek(
(m) -> m.setChildren(getChildrenList(m, trees))
).collect(Collectors.toList());
}
public static List<TreeSelect> getChildrenList(TreeSelect tree, List<TreeSelect> list){
return list.stream().filter(item -> Objects.equals(item.getParentId(), tree.getId())).peek(
(item) -> item.setChildren(getChildrenList(item, list))
).collect(Collectors.toList());
}
public static List<TreeSelect> buildTreeByStream(List<TreeSelect> trees){
List<TreeSelect> list = trees.stream().filter(item -> item.getParentId() == 0L).collect(Collectors.toList());
Map<Long, List<TreeSelect>> map = trees.stream().collect(Collectors.groupingBy(TreeSelect::getParentId));
recursionFnTree(list, map);
return list;
}
public static void recursionFnTree(List<TreeSelect> list, Map<Long, List<TreeSelect>> map){
for (TreeSelect treeSelect : list) {
List<TreeSelect> childList = map.get(treeSelect.getId());
treeSelect.setChildren(childList);
if (null != childList && 0 < childList.size()){
recursionFnTree(childList,map);
}
}
}
public static List<TreeSelect> buildTree(List<TreeSelect> trees) {
List<TreeSelect> returnList = new ArrayList<>();
List<Long> tempList = new ArrayList<>();
for (TreeSelect tree : trees) {
tempList.add(tree.getId());
}
for (TreeSelect treeSelect : trees) {
if (!tempList.contains(treeSelect.getParentId())) {
recursionFn(trees, treeSelect);
returnList.add(treeSelect);
}
}
if (returnList.isEmpty()) {
returnList = trees;
}
return returnList;
}
private static void recursionFn(List<TreeSelect> list, TreeSelect t) {
List<TreeSelect> childList = getChildList(list, t);
t.setChildren(childList);
for (TreeSelect tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
private static List<TreeSelect> getChildList(List<TreeSelect> list, TreeSelect t) {
List<TreeSelect> tlist = new ArrayList<>();
for (TreeSelect n : list) {
if (ObjectUtil.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
tlist.add(n);
}
}
return tlist;
}
private static boolean hasChild(List<TreeSelect> list, TreeSelect t) {
return getChildList(list, t).size() > 0;
}
static class TreeSelect implements Serializable {
private Long id;
private String label;
private Long parentId;
private List<TreeSelect> children;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public List<TreeSelect> getChildren() {
return children;
}
public void setChildren(List<TreeSelect> children) {
this.children = children;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
}
}
执行结果
