Loading

将列表数据组成一棵树

列表数据结构

假设有这样一个数据集合,其列表元素结构为:

/**
 * 这部分数据可能是调第三方api或者查询的数据库
 */
@Builder
@Data
public class RegionNode {
	private String id; // 区域id
	private String pid; // 区域父id
	private String name; // 区域名称
}

数据

id pid name
410000 0 河南
410100 410000 郑州
410103 410100 二七区
410105 410100 金水区
410102 410100 中原区
410106 410100 上街区

将列表数据拼成一棵树

定义结构体

/**
 * 返回给前端页面
 */
@Data
public class TreeNode {
	private String id; // 区域id
    private String pid; // 区域父id
	private String name; // 区域名称
    private List<TreeNode> children; // 子区域集合
    
    public void addChild(TreeNode child){
        if(this.children == null){
            this.children = new ArrayList<>();
        }
        this.children.add(child);
    }
    
}

转换方法

public static TreeNode convert(List<RegionNode> regionNodeList){

    Map<String,TreeNode> map = new HashMap<>();

    for(RegionNode regionNode : regionNodeList){
        TreeNode treeNode = new TreeNode();
        BeanUtils.copyProperties(regionNode, treeNode);
        map.put(regionNode.getId(), treeNode);
    }

    TreeNode root = null;
    for (Map.Entry<String, TreeNode> entry : map.entrySet()) {

        // 找到根节点(把哪个作为根节点可以配置)
        if("0".equals(entry.getValue().getPid())){
            root = entry.getValue();
            continue;
        }

        // 找到当前节点的父节点
        TreeNode parent = map.get(entry.getValue().getPid());
        if(parent != null){
            parent.addChild(entry.getValue());
        }

    }

    return root;

}

验证

public static void main(String[] args) {

    List<RegionNode> regionNodeList = new ArrayList<>();
    RegionNode regionNode1 = RegionNode.builder().id("410000").pid("0").name("河南").build();
    RegionNode regionNode2 = RegionNode.builder().id("410100").pid("410000").name("郑州").build();
    RegionNode regionNode3 = RegionNode.builder().id("410103").pid("410100").name("二七区").build();
    RegionNode regionNode4 = RegionNode.builder().id("410105").pid("410100").name("金水区").build();
    RegionNode regionNode5 = RegionNode.builder().id("410102").pid("410100").name("中原区").build();
    RegionNode regionNode6 = RegionNode.builder().id("410106").pid("410100").name("上街区").build();

    regionNodeList.add(regionNode1);
    regionNodeList.add(regionNode3);
    regionNodeList.add(regionNode4);
    regionNodeList.add(regionNode5);
    regionNodeList.add(regionNode6);
    regionNodeList.add(regionNode2);

    TreeNode treeNode = convert(regionNodeList);
    System.out.println(treeNode);

}

image

结语

  1. convert方法中循环了2次,其实可以对regionNodeList先根据id排序,保证上层区域在最列表的前面,可以一次循环就搞定。
  2. 如果数据量很大的话这种方式不适合,组成一颗庞大的树给到前端页面渲染起来也会很慢。可以根据pid逐层查询下级列表。
posted @ 2023-08-02 15:40  CharltonClown  阅读(18)  评论(0编辑  收藏  举报