java 树形层级往上汇总属性值

1.BaseTree

package com.aprilz.common.core.util.tree;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Aprilz
 * @date 2023/3/6-8:56
 * @description Tree基类
 */
@Data
public class BaseTree implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "id", required = true, example = "32741")
    private Long id;

    @ApiModelProperty(value = "父id,顶级父id默认为0", required = true)
    private Long parentId;

    @ApiModelProperty(value = "排序,从小到大")
    private Integer sort;

    @ApiModelProperty(value = "父ids,顶级父ids默认为0,如果有多层结构则表现为0::1::4", required = true)
    private String parentIds;

    @ApiModelProperty(value = "排序,创建时间")
    private LocalDateTime updateTime;

    @ApiModelProperty(value = "子集")
    private List<? extends BaseTree> childList;


    @ApiModelProperty(value = "是否计算本身")
    private boolean addSelf=false;

}

TreeUtil

package com.aprilz.common.core.util.tree;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson2.util.TypeUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 构建树形结构工具类
 *
 * @author Aprilz
 * @date 2023/3/6-9:13
 */
@SuppressWarnings("unused")
public class TreeUtil {


    /**
     * 查找最内层子叶子节点数据(没有子节点的节点)
     * @param treeList(为排序完后的树)
     */
    public static List<? extends BaseTree>  findMinNodes(List<? extends BaseTree> treeList) {
        List<BaseTree> resultList = new ArrayList<>();
        if(CollUtil.isNotEmpty(treeList)){
            for (BaseTree tree : treeList) {
                List<BaseTree> childList = (List<BaseTree>) tree.getChildList();
                if(CollUtil.isNotEmpty(childList)){
                    resultList.addAll(findMinNodes(childList));
                    //无节点则直接加入
                }else{
                    resultList.add(tree);
                }
            }
        }
        return resultList;
    }



    /**
     * 树形层级 往上统计
     *  用法 :  TreeUtil.treeCalculatePlus(respVOS,"projectNum");
     *
     * @param treeList   树层级List
     * @param fieldNames 可变长属性名
     */
    public static void treeCalculatePlus(List<? extends BaseTree> treeList, String... fieldNames) {
        if (fieldNames.length == 0) {
            throw new IllegalArgumentException("最少需要一个属性名");
        }
        if (CollUtil.isNotEmpty(treeList)) {
            for (BaseTree tree : treeList) {
                List<BaseTree> childList = (List<BaseTree>) tree.getChildList();
                if (CollUtil.isNotEmpty(childList)) {
                    List<BaseTree> collect = childList.stream().filter(tmp -> !tmp.isAddSelf()).collect(Collectors.toList());
                    //存在未计算的子级则继续重复调用,之后再计算自身
                    if (collect.size() > 0) {
                        treeCalculatePlus(childList, fieldNames);
                    }
                    //无节点则直接计算
                    for (String fieldName : fieldNames) {
                        Object fieldValue = Objects.isNull(ReflectUtil.getFieldValue(tree, fieldName)) ? 0 : ReflectUtil.getFieldValue(tree, fieldName);
                        Integer sum = TypeUtils.toInteger(fieldValue);
                        for (BaseTree child : childList) {
                            sum += TypeUtils.toInteger( Objects.isNull(ReflectUtil.getFieldValue(child, fieldName)) ? 0 : ReflectUtil.getFieldValue(child, fieldName));
                        }
                        ReflectUtil.setFieldValue(tree, fieldName, sum);
                    }
                }
                //计算完成标识
                tree.setAddSelf(true);
            }
        }
    }


}

addSelf默认为false,使用addSelf属性来判断是否计算过,没计算过的,递归往下,直至没有子级为参与计算,此时汇总属性值参与汇总到父级。

gihub代码地址
https://github.com/aprilz-code/tiny.git
https://github.com/aprilz-code/cloud.git

你可能感兴趣的:(java)