递归构建行政区域树

概述

实际开发中,有时需要自己构建出一颗行政区域树或某个组织的组织架构树,如北京市-朝阳区、北京市-海淀区、上海市-松江区等,这种需求一般用递归实现较为简单、易理解。

说明

以下代码中提供的各个行政区域的编码为方便起见是自定义的,真实项目中可能需要爬取第三方网站的真实数据获得。(各个行政区的编码是统一规定的)

实现

package com.lovehena.bilibili.recursion;

import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/*
 *   递归构建行政地区树:
 *       浙江省
 *           杭州市
 *               余杭区
 *               滨江区
 *               拱墅区
 *               萧山区
 *       上海市
 *           闵行区
 *           松江区
 *       北京市
 *           海淀区
 *           朝阳区
 * */
@Slf4j
public class BuildAreaTree {

    private static List<AreaVo> allAreas = new ArrayList<>();

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private static class AreaVo {
        private String code;  // 行政区编码
        private String parentCode;  // 上级行政区编码
        private String label; // 行政区中文名
        private int level; // 省市区等级
        private List<AreaVo> children; // 下辖行政区

        public AreaVo(String code, String parentCode, String label, int level) {
            this.code = code;
            this.parentCode = parentCode;
            this.label = label;
            this.level = level;
        }

        @Override
        public String toString() {
            return JSONUtil.toJsonStr(this); // 利用hutool提供的json模块进行json格式化输出 便于查看
        }
    }

    public static void main(String[] args) {
        initData(); // 初始化数据
        List<AreaVo> tree = buildAreaTree();// 构建组织树
        log.info("tree:{}",tree);
    }

    /**
     * 构造初始数据
     */
    private static void initData() {
        // 浙江部分省市区数据
        allAreas.add(new AreaVo("zhejiang", "", "浙江省", 1)); // 真实的各个省市区的行政编码可以从网上搜索获取
        allAreas.add(new AreaVo("hangzhou", "zhejiang", "杭州市", 2));
        allAreas.add(new AreaVo("yuhang", "hangzhou", "余杭区", 2));
        allAreas.add(new AreaVo("binjiang", "hangzhou", "滨江区", 2));
        allAreas.add(new AreaVo("xiaoshan", "hangzhou", "萧山区", 2));
        allAreas.add(new AreaVo("gongshu", "hangzhou", "拱墅区", 2));
        // 添加三级行政区
        allAreas.add(new AreaVo("cangqian", "yuhang", "仓前街道", 3));

        // 上海市部分区数据
        allAreas.add(new AreaVo("shanghai", "", "上海市", 1));
        allAreas.add(new AreaVo("minhang", "shanghai", "闵行区", 2));
        allAreas.add(new AreaVo("songjiang", "shanghai", "松江区", 2));

        // 北京市部分区数据
        allAreas.add(new AreaVo("beijing", "", "北京市", 1));
        allAreas.add(new AreaVo("haidian", "beijing", "海淀区", 2));
        allAreas.add(new AreaVo("chaoyang", "beijing", "朝阳区", 2));

    }

    /**
     * 构建组织树
     *
     * @return 构建完成的组织树
     */
    private static List<AreaVo> buildAreaTree() {
        // 过滤一级行政组织
        List<AreaVo> level1Areas = allAreas.stream().filter(item -> item.getLevel() == 1).collect(Collectors.toList());
        for (AreaVo level1Area : level1Areas) {
            level1Area.setChildren(getChildren(level1Area.getCode()));
        }
        // 构建好的组织树中 第一层是一级行政区如 浙江、上海、北京
        // 这些一级行政区下挂着二级行政区 各个二级行政区下又挂着三级行政区 以此类推
        // 故返回构建好的一级行政区即可
        return level1Areas;
    }

    /**
     * 递归获取某一行政组织的下级行政组织
     *
     * @param code 行政组织编码
     * @return
     */
    private static List<AreaVo> getChildren(String code) {
        List<AreaVo> children = allAreas.stream().filter(item -> item.getParentCode().equals(code)).map(item -> {
            item.setChildren(getChildren(item.getCode())); // 每一个下级行政组织可能又有自己的下级行政组织 递归获取 封装后返回
            return item;
        }).collect(Collectors.toList());
        return children;
    }
}

输出

输出
格式化以后便于查看
递归构建行政区域树_第1张图片

最后

好了,如果对你有帮助,欢迎点个免费的赞哦。

你可能感兴趣的:(java,java,开发语言,后端,ide,算法)