循环去重拼接成树形结构,栈溢出问题。


 public List<TreeList> select() {
        //oneTree为返回值,里面存放的是只有一级数据,一级为subarea
        List<TreeList> dList = testService.list(new LambdaQueryWrapper<TreeList>());
        List<TreeList> oneTree = dList.stream().filter(distinctByKey1(item -> item.getSubarea())).collect(Collectors.toList());
        oneTree.forEach(one -> {
            one.setLabel(one.getSubarea());
            //对应一级的二级。(应为有三级数据,所以二级数据会重名)
            List<TreeList> twoTree  = dList.stream().filter(item -> item.getSubarea().equals(one.getSubarea())).collect(Collectors.toList());
            //去重
            twoTree = twoTree.stream().filter(distinctByKey1(item -> item.getStname())).collect(Collectors.toList());
            if (!twoTree.isEmpty()) {
                twoTree.forEach(two -> {
                    two.setLabel(two.getStname());
                    ArrayList<TreeList> treeLists = new ArrayList<>();
                    TreeList treeList = new TreeList();
                    treeList.setLabel("三级自定义名称");
                    //四级数据,四级的二级名称,对应二级的二级名称。
                    List<TreeList> fourTree = dList.stream().filter(item -> item.getStname().equals(two.getStname())).collect(Collectors.toList());
                    fourTree.forEach(item->item.setLabel(item.getDvname()));
                    treeList.setChildren(fourTree);
                    treeLists.add(treeList);
                    two.setChildren(treeLists);
                });
            }
            one.setChildren(twoTree);
        });
        System.out.println(oneTree);
        return oneTree;
    }


 static <T> Predicate<T> distinctByKey1(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }



@Data
@TableName("test")
public class TreeList {

    @TableField(value = "subarea")
    private String subarea;//区域1级

    @TableField(value = "stname")
    private String stname;//首端厂站名2级

    @TableField(value = "dvname")
    private String dvname;//设备名称3级
    @TableField(exist = false)
    private String name;//三级自定义名称
    @TableField(exist = false)
    private String label;
    @TableField(exist = false)
    private List<TreeList> children = new ArrayList<>();//子节点


    @Override
    public String toString() {
        return "TreeList{" +
                "subarea='" + subarea + '\'' +
                ", stname='" + stname + '\'' +
                ", dvname='" + dvname + '\'' +
                ", name='" + name + '\'' +
                ", label='" + label + '\'' +
                ", children=" + children +
                '}';
    }
}

输出的时候,应该是遍历而不是单纯的输出

这代码看着有点点难受呀,树形结构的组装,可以用遍历队列,递归来完成。