Java无限级分类的循环---子级的分类

懒驴 2021年12月01日 1,660次浏览

我们在项目开发中,经常会遇到存在上下级关系的数据,比如商品类型的级别分类,食品类下分类熟食类和肉食类,肉食类下又分了海鲜类和家禽类,等等诸如此类的数据结构。
以下我将以公司部门的层级结构来为例子,详细介绍Java使用循环来做层级结构化分类数据。

部门实体类

部门实体类的数据库设计是这样的,一个部门有名称、编号,如果该部门没有上级,那么父级ID字段则为空;如果该部门存在上级,那么其父级ID字段则为父级部门的ID。

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrganizationFrameInfo extends Model<OrganizationFrameInfo> {
    public static final long serialVersionUID = 1L;
    public OrganizationFrameInfo(){}

    //属性
    private Long orgfraId;                  //主键ID
    private String orgfraStrId;             //字符主键ID
    private String orgfraName;              //组织部门名称
    private Integer orgfraType;             //类型,1为最高级,2为第二级,3为第三级,以此类推...
    private String orgfraNo;                //部门编号
    private String orgfraParentId;          //上级组织字符ID
    private String addDate;                 
    private Integer stratus;                

}

部门Pojo实体类

@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrganizationFrameInfoPojo extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    public OrganizationFrameInfoPojo(){}

    //属性
    private Long orgfraId;                  //主键ID
    private String orgfraStrId;             //字符主键ID
    private String orgfraName;              //组织部门名称
    private Integer orgfraType;             //类型,1为最高级,2为第二级,3为第三级,以此类推...
    private String orgfraNo;                //部门编号
    private String orgfraParentId;          //上级组织字符ID
    private String addDate;                 
    private Integer stratus;                

    //子级部门信息
    private List<OrganizationFrameInfoPojo> children;

    /***此处省略了属性的Get Set方法,自行补充***/

    //将实体类转化为Pojo类的方法
    public static OrganizationFrameInfoPojo entityToPojo(OrganizationFrameInfo entity){
        OrganizationFrameInfoPojo pojo=new OrganizationFrameInfoPojo();
        BeanUtils.copyProperties(entity, pojo);
        return pojo;
    }

    public List<OrganizationFrameInfoPojo> getChildren() {
        return children;
    }

    public void setChildren(List<OrganizationFrameInfoPojo> children) {
        this.children = children;
    }
}

业务处理数据层级结构化(重点)

以下是将数据层级结构化的方法

/***
  * 部门层级分类
  * 循环获取字典数据 树
  * 子ID必须小于父ID
  * 查询所有数据时必须按照ID从小到大排序
  * 换而言之就是父级必须在前面
  */
public List<OrganizationFrameInfoPojo> getSelectOrganizationAllList(OrganizationFrameInfoPojo organization) {
	//查询所以出数据
        List<OrganizationFrameInfo> entityList=organizationFrameInfoMapper.listAll(organization);
        //转化为Pojo
        List<OrganizationFrameInfoPojo> pojoList=new ArrayList<>();
        entityList.forEach(entity ->pojoList.add(OrganizationFrameInfoPojo.entityToPojo(entity)));
        //最终输出的树
        List<OrganizationFrameInfoPojo> pojoResult=new ArrayList<>();
        //以ID为键保存每一条数据
        Map<String, OrganizationFrameInfoPojo> map=new HashMap<>();
        for(OrganizationFrameInfoPojo pojo:pojoList){
            String strId=pojo.getOrgfraParentId();
            map.put(pojo.getOrgfraStrId(), pojo);
            //如果在map不存在当前数据的父ID为键的数据,则为0,保存在输出树中
            if(null==map.get(strId)){
                pojoResult.add(pojo);
            }else{
                //如果在map存在当前数据的父ID为键的数据,则将当前数据加入到父节点的children中
                OrganizationFrameInfoPojo one=map.get(strId);
                if(null==one.getChildren()){
                    one.setChildren(new ArrayList<>());
                }
                one.getChildren().add(pojo);
            }
        }
	return pojoResult;
}