java 利用递归,list,map实现树形结构,根据节点找到父节点,根据节点找到子节点

java 利用递归,list,map实现树形结构,根据节点找到父节点,根据节点找到子节点


前言

以下代码说明:实现的数据都只是基于以下## 2.数据库结构

一、部门树的实现方法一(Map)

1.部门树结构

{
			"id": 1,
			"orgCode": "000012",
			"parentCode": null,
			"orgName": "xxxx省监督管理局",
			"children": [
				{
					"id": 2,
					"orgCode": "00001201",
					"parentCode": "000012",
					"orgName": "xxx区管理局",
					"children": [
						{
							"id": 5,
							"orgCode": "000012011",
							"parentCode": "00001201",
							"orgName": "xxx村管理局",
							"children":""
						}
				}
			]
		}

2.数据库结构

在这里插入图片描述

3.vo对象:

@Data
public class OrganizationVo {

    /**
     * 部门id
     */
    private Integer id;

    /**
     * 部门编码
     */
    private String orgCode;

    /**
     * 部门父编码
     */
    private String parentCode;


    /**
     * 部门名称
     */
    private String orgName;

    /**
     * 子部门列表  这里用list类型也是一样的
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Collection<OrganizationVo> children;
 }

4.代码实现

public List<OrganizationVo> getOrgAll(){
        //获取所有部门
        List<OrganizationVo> organizationVos = xxxx方法.listAll();
        List<OrganizationVo> list = new ArrayList<>();
        Map<String , OrganizationVo> map = new HashMap<>();
        //把所有部门转化成map结构,key为组织编码,value为组织对象
        for (OrganizationVo organizationVo : organizationVos) {
            if (StringUtils.isNotBlank(organizationVo.getParentCode())){
                map.put(organizationVo.getOrgCode(), organizationVo);
            }
        }
		//实现树形结构
        for (OrganizationVo organizationVo : organizationVos) {
            String code = organizationVo.getParentCode();
            OrganizationVo parent = map.get(code);
            //根据最高级组织中parentCode为空或者以parentCode为组织编码查不到组织的原理,把最高级组织对象add到list结构中
            if (ObjectUtils.isEmpty(parent)){
                list.add(organizationVo);
            }else {
                Collection<OrganizationVo> children = parent.getChildren();
                if (CollectionUtils.isEmpty(children)){
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(organizationVo);
            }
        }
        return list;
    }

二、部门树的实现方法二(MyBatis)

虽然可以实现但是查询速度很慢 效率低 在多数据时不推荐使用

1.方法

List<OrganizationVo> listAll();

2.mybatis实现


 <resultMap id="ResourceResultMap" type="xxxx.xxxx.OrganizationVo">
    <collection property="children" column="{orgParentCode=orgCode}" select="getChildrenTree"/>
  </resultMap>

  <select id="listAll" resultMap="ResourceResultMap">
    select id, org_code orgCode, org_parent_code parentCode, org_name orgName, creator
    from sys_organization
  </select>
  <select id="getChildrenTree" resultType="xxxx.xxxx.OrganizationVo">
    select *
    from sys_organization where org_parent_code=#{orgParentCode}
  </select>

三、通过orgCode(节点编码)返回包含此orgCode在内的所有子orgCode列表(可以实现获取该orgCode下(包括子集)所有对应的用户)

1.使用递归实现

代码实现:

string orgCode="00001201"
ArrayList<String> list = new ArrayList<>();
//查询所有组织
 List<OrganizationVo> all = xxxxx方法.listAll();
 //递归
 List<String> codeList = getChildrenCode(orgCode, all, list);
 codeList.add(orgCode);
 System.out.println(codeList);  //["000012011","00001201"]

2.递归方法

代码如下:

public List<String> getChildrenCode(String orgCode, List<OrganizationVo> all, List<String> list) {
        for (OrganizationVo d : all) {
            if (orgCode.equals(d.getParentCode())) {
                list.add(d.getOrgCode());
                getChildrenCode(d.getOrgCode(), all, list);
            }
        }
        return list;
    }

四、通过orgCode返回所有父级code

1.方法

/**
     * 根据部门id查询部门父级
     * @param orgCode
     * @param sysOrganizations
     * @return
     */
    public void completeOrg() {
		String orgCode="000012011"
		//查询所有组织
		 List<OrganizationVo> sysOrganizations = xxxxx方法.listAll();
        // key是 资源id, value 是 父id
        Map<String, String> collect = sysOrganizations
                .stream()
                .collect(
                        Collectors.toMap(
                                SysOrganization::getOrgCode,
                                it -> (it.getOrgParentCode() == null) ? it.getOrgCode() : it.getOrgParentCode(),
                                (v1, v2) -> v2
                        )
                );
        Set<String> resSet = new HashSet<>();
        orgFindParent(resSet, collect, orgCode);
        String a[]=resSet.stream()
                .map(String::valueOf).sorted()
                .toArray(String[]::new);
        System.out.println(a);//["000012","00001201","000012011"]
                
    }

2.递归方法

	/**
     *     部门: 路径压缩,查询父节点
     * @param
     */
    private static void orgFindParent(Set<String> orgSet, Map<String,String >  orgMap  , String orgCode) {

        if (StringUtils.isNotBlank(orgCode)){
            while (!orgCode.equals(orgMap.get(orgCode))) {
            	//亲身教训:如果不加一下判断的话,如果orgMap.get(orgCode))为空时(当部门有父级code,但是父级部门又不存在数据库时),会进入死循环
                if (StringUtils.isNotBlank(orgMap.get(orgCode))){
                    orgSet.add(orgCode);
                    String parent = orgMap.get(orgCode);
                    if (StringUtils.isNotBlank(parent)) {
                        orgMap.put(orgCode, orgMap.get(parent));
                        orgCode = parent;
                    }
                    orgSet.add(orgCode);
                }else {
                    //若orgCode为空时则移除,(当父级parentCode存在,但是却没有父级部门信息时,应移除父级code)
                    orgSet.remove(orgCode);
                    break;
                }

            }
        }
    }

五、根据部门编码,获取二级code

1.方法

		String a="000012011";
        String secondOrgCode=null;
        SysOrganization organization=new SysOrganization();
        secondOrgCode= secondOrganization(a,secondOrgCode,organization);
        System.out.println("secondOrgCode = " + secondOrgCode); //00001201

2.递归方法

    private String secondOrganization(String orgCode,String secondOrgCode,SysOrganization organization) {
        secondOrgCode=organization.getOrgCode();
        organization= organizationService.getByOrgCode(orgCode);
        if (!ObjectUtils.isEmpty(organization.getId()) ){
            if (organizationService.getByOrgCode(organization.getOrgParentCode()).getId()!=null&&StringUtils.isNotBlank(organization.getOrgParentCode())){
                return this.secondOrganization(organization.getOrgParentCode(),secondOrgCode,organization);
            }

        }
        return secondOrgCode;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值