Java组装独立叶子节点树结构

业务场景:属性树下面挂标签
例如:基本信息/性别 标签:男、女
属性层级和标签分别为不同的实体
组装全属性树结构方法:

public List<Node> selectAllLabel(String bchCde) {
        List<Label> labelList = labelMapper.selectAll(bchCde);
        //查询出所有层级(多个模板)
        List<FileLabelTpl> all = fileLabelTplMapper.selectAllFileLabelTpl(bchCde);
        List<Node> rootList = new ArrayList<>();
        List<Node> childList = new ArrayList<>();
        if (!ObjectIsNullUtil.isNullOrEmpty(all)){
            all.stream().forEach(fileLabelTpl -> {
                if (ObjectIsNullUtil.isNullOrEmpty(fileLabelTpl.getCpsParentNodeNo())) {
                    Node rootNode = new Node();
                    rootNode.setId(fileLabelTpl.getCpsOutNodeNo());
                    rootNode.setValue(fileLabelTpl.getCpsOutNodeNo());
                    rootNode.setLabel(fileLabelTpl.getCpsTplNodeName());
                    rootNode.setNodeFullType(fileLabelTpl.getCpsTplNodeName());
                    rootList.add(rootNode);
                } else {
                    Node childNode = new Node();
                    childNode.setId(fileLabelTpl.getCpsOutNodeNo());
                    childNode.setValue(fileLabelTpl.getCpsOutNodeNo());
                    childNode.setLabel(fileLabelTpl.getCpsTplNodeName());
                    childNode.setParentNo(fileLabelTpl.getCpsParentNodeNo());
                    childList.add(childNode);
                }
            });
            if (!ObjectIsNullUtil.isNullOrEmpty(labelList)) {
                labelList.stream().forEach(label -> {
                    if (!ObjectIsNullUtil.isNullOrEmpty(rootList)) {
                        rootList.stream().forEach(root -> {
                            if (label.getCpsOutNodeNo().equals(root.getId())) {
                                root.setCreateChild(false);
                            }
                        });
                    }
                    if (!ObjectIsNullUtil.isNullOrEmpty(childList)) {
                        childList.stream().forEach(child -> {
                            if (label.getCpsOutNodeNo().equals(child.getId())) {
                                child.setCreateChild(false);
                            }
                        });
                    }
                });
                labelList.stream().forEach(label -> {
                    Node labelNode = new Node();
                    labelNode.setId(label.getCpsLabelNo());
                    labelNode.setValue(label.getCpsLabelNo());
                    labelNode.setLabel(label.getCpsLabelName());
                    labelNode.setParentNo(label.getCpsOutNodeNo());
                    labelNode.setCreateChild(false);
                    childList.add(labelNode);
                });
            }
            //将子节点挂在父节点上面
            rootList.stream().forEach(rootNode -> {
                rootNode.setChildren(fileLabelTplService.childList(rootNode.getId(), childList, rootNode.getNodeFullType()));
            });
        }
        return rootList;
    }




    public List<Node> childList(String id, List<Node> list, String nodeFullType){
        List<Node> childList = new ArrayList<>();
        list.stream().forEach(node -> {
            if (id.equals(node.getParentNo())){
                node.setNodeFullType(nodeFullType + "/" + node.getLabel());
                node.setNodeParentFullType(nodeFullType);
                childList.add(node);
            }
        });

        /** 递归拼装树结构 */
        if (!ObjectIsNullUtil.isNullOrEmpty(childList)){
            childList.stream().forEach(node -> {
                if(!ObjectIsNullUtil.isNullOrEmpty(childList(node.getId(), list, node.getNodeFullType()))){
                    node.setChildren(childList(node.getId(), list, node.getNodeFullType()));
                }
            });
        }
        return childList;
    }

节点实体:

package com.fantaike.cps.dto;

import lombok.Data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

@Data
public class Node implements Serializable {
    private static final long serialVersionUID = 1L;

    private String id;

    private String label;

    private String value;

    private List<Node> children;

    private String parentNo;

    private String level;

    private boolean createChild = true;

    private String NodeFullType;

    private String NodeParentFullType;

}

以标签或层级为条件拼装树结构

    /**
     * @Description: 递归获取父节点
     * @param outNodeNo
     * @param tpls
     * @param list
     * @Date: 2019/7/16 15:25
     * @Author: liujianing
     * @Return java.util.List
     * @Throws
     */
    private List getParentNodes(String outNodeNo, List<LabelTpl> tpls, List list) {
        if(outNodeNo == null || "".equals(outNodeNo)){
            return list;
        }

        Optional<LabelTpl> tpOpl = tpls.stream().filter(tpl -> outNodeNo.equals(tpl.getCpsOutNodeNo())).findFirst();
        if(tpOpl.isPresent()){
            FileLabelTpl tpl = tpOpl.get();
            if ( tpl.getCpsParentNodeNo() != null && !"".equals(tpl.getCpsParentNodeNo())){
                list.add(tpl.getCpsParentNodeNo());
            }
            getParentNodes(tpl.getCpsParentNodeNo(), tpls, list);
        }
        return list;
    }


    /**
     * 模糊查询标签返回思维导图 liujianing
     * @param labelNo 标签数组
     * @param nodeNo 节点数组
     * @param bchcde 机构
     * @return 标签思维导图
     */
    @Override
    public List<NodeLabelMap> getTagMap(String[] labelNo, String[] nodeNo, String bchcde){

        //层级list
        List<FileLabelTpl> allTpl = null;
        //标签list
        List<Label> labelList = null;


        //标签层级条件都为空,以所有标签查询
        if((labelNo == null || labelNo.length ==0) && (nodeNo == null || nodeNo.length ==0)){

            labelList = labelMapper.selectAll(bchcde);

        }

        //标签条件不为空
        if(labelNo != null && labelNo.length > 0){

            labelList = labelMapper.selectByIdSet(bchcde, labelNo);

            //层级条件不为空,取与标签的交集
            if(nodeNo != null && nodeNo.length > 0){

                List<String> nodeList = Arrays.asList(nodeNo);
                //查询标签数据(带层级)
                List<LabelTpl> labelTpls = labelMapper.selectLabelTpl(bchcde, labelNo);

                //通过标签ID分组
                Map<String, List<LabelTpl>> groupLabels =
                        labelTpls.stream().collect(Collectors.groupingBy(LabelTpl::getCpsLabelNo));

                //将outno拼入map方便后续取值
                Map<String,String> outMap = labelList
                        .stream().filter(d -> d.getCpsLabelNo() != null && d.getCpsOutNodeNo() != null)
                        .collect(Collectors.toMap(Label::getCpsLabelNo, Label::getCpsOutNodeNo, (key1, key2) -> key2, HashMap::new));

                //有交集的标签id集合
                List<String> labels = new ArrayList<>();

                //循环标签进行判断
                for(Map.Entry<String, List<LabelTpl>> entry : groupLabels.entrySet()){
                    String mapKey = entry.getKey();
                    List<LabelTpl> tplList = entry.getValue();

                    List<String> listL = getParentNodes(outMap.get(mapKey), tplList, new ArrayList());
                    listL.add(outMap.get(mapKey));

                    //如果有交集
                    if(!Collections.disjoint(nodeList,listL)){
                        labels.add(mapKey);
                    }
                }
                if(ObjectIsNullUtil.isNullOrEmpty(labels)){
                    //返回空
                    return new ArrayList<>();

                }
                labelList = labelMapper.selectLabelNo(labels);

            }
        }


        //只选择了层级
        if((labelNo == null || labelNo.length ==0) && (nodeNo != null && nodeNo.length >0)){

            //在层级中的标签id集合
            List<String> labels = new ArrayList<>();
            //层级下的叶子节点集合
            List<String> leafs = new ArrayList<>();
            List<String> nodeList = Arrays.asList(nodeNo);

            //查询同根节点下所有层级数据
            List<LabelTpl> labelTpls = labelMapper.selectLabelTplByNode(bchcde, nodeNo);
            //查询同根节点下所有叶子节点id
            List<String> leftNodeList = fileLabelTplMapper.selectAllLeafNode(bchcde, nodeNo);

            for (String s : leftNodeList) {
                //递归查询叶子节点所有的相关节点
                List<String> listL = getParentNodes(s, labelTpls, new ArrayList());
                listL.add(s);
                //如果有交集
                if(!Collections.disjoint(nodeList,listL)){
                    leafs.add(s);
                }
            }

            if(ObjectIsNullUtil.isNullOrEmpty(leafs)){
                //返回空
                return new ArrayList<>();

            }
            labels = labelMapper.selectLabelsByLeafs(bchcde, leafs);

            if(labels.isEmpty()){
                return new ArrayList<>();
            }
            labelList = labelMapper.selectLabelNo(labels);
        }


        if(ObjectIsNullUtil.isNullOrEmpty(labelList)){
            //返回空
            return new ArrayList<>();

        }

        //获取涉及到的所有的层级对象
        allTpl = fileLabelTplService.selectByOutNodeNo(labelList);


        //开始组装返回的树结构
        List<NodeLabelMap> result = packageTagTree(labelList, allTpl);

        return result;

    }


    /**
     * @Description: 组装标签树
     * @param labelList 标签列表
     * @param allTpl 相关层级列表
     * @Date: 2019/7/18 10:22
     * @Author: liujianing
     * @Return java.util.List<com.fantaike.cps.dto.NodeLabelMap>
     * @Throws
     */
    @Override
    public List<NodeLabelMap> packageTagTree(List<Label> labelList, List<FileLabelTpl> allTpl){

        //层级map
        Map<String, String> tplMap = new HashMap();
        //标签map
        Map<String, String> labelMap = new HashMap();
        //构造层级属性名称map
        allTpl.stream().forEach(fileLabelTpl -> {
            tplMap.put(fileLabelTpl.getCpsOutNodeNo(), fileLabelTpl.getCpsTplNodeName());
        });
        //结果list
        List<NodeLabelMap> result = new ArrayList<>();
        Set<String> set = new HashSet<>();
        List<List<String>> listColl = new ArrayList<>();
        if (!ObjectIsNullUtil.isNullOrEmpty(labelList)) {
            //遍历标签列表
            for (Label label : labelList) {
                List<String> labelTplNo = new ArrayList();
                labelMap.put(label.getCpsLabelNo(), label.getCpsLabelName());
                String outNoStr = label.getCpsOutNodeNo();
                labelTplNo.add(label.getCpsLabelNo());
                labelTplNo.add(outNoStr);
                //获取标签的全层级id 从根节点到叶子节点
                List<String> ltplList = getParentList(outNoStr, allTpl,labelTplNo);
                //将全层级id放入一个集合
                listColl.add(ltplList);
                //对同一层级属性下的标签进行去重
                if (ltplList != null && ltplList.size() > 0){
                    //得到所有根节点
                    set.add(ltplList.get(ltplList.size() - 1));
                }
            }

            //对同一层级属性下的标签进行分类
            if (set != null && set.size() > 0 && listColl != null && listColl.size() > 0){
                List<List<List<String>>> liss = new ArrayList();
                //将标签全层级挂在根节点上
                for (String s : set){
                    List<List<String>> li = new ArrayList();
                    for(List<String> lis : listColl){
                        if(s.equals(lis.get(lis.size() - 1))){
                            li.add(lis);
                        }
                    }
                    liss.add(li);
                }
                //为每个标签封装对象
                for ( List<List<String>> a: liss) {
                    List<NodeLabelMap> nlList = new ArrayList<>();
                    for (List<String> b : a) {
                        //多个相同层级下对象
                        for (int i = 0; i < b.size(); i++) {
                            NodeLabelMap nl = new NodeLabelMap();
                            nl.setValue1(b.get(i));
                            nl.setChildren(null);
                            if(!ObjectIsNullUtil.isNullOrEmpty(labelMap.get(b.get(i)))){
                                nl.setType("label");
                                nl.setName(labelMap.get(b.get(i)));
                            }else{
                                nl.setType("category");
                                nl.setName(tplMap.get(b.get(i)));
                            }
                            if (i + 1 > b.size() - 1) {
                                //根节点
                                nl.setParentNo(null);
                            }else {
                                nl.setParentNo(b.get(i + 1));
                            }
                            nlList.add(nl);
                        }
                    }
                    if (nlList != null && nlList.size() > 0){
                        //对象去重,去掉重复的层级
                        List<NodeLabelMap> all = removeDuplicateOrder(nlList);
                        NodeLabelMap root = null;
                        for (NodeLabelMap nodeLabel : all) {
                            if(ObjectIsNullUtil.isNullOrEmpty(nodeLabel.getParentNo())){
                                root = nodeLabel;
                            }
                        }
                        //遍历子对象,封装拼成树结构
                        List<NodeLabelMap> chilList = getChildListMap(root.getValue1(),all);
                        /** 分组统计标签数量返回给前端 */
                        Map<String, List<NodeLabelMap>> glist = all.stream().collect(Collectors.groupingBy(e -> e.getType()));
                        int count = glist.get("label").size();
                        root.setChildren(chilList);
                        root.setCount(count);
                        result.add(root);
                    }
                }
            }
        }
        return result;
    }


    private List<NodeLabelMap> removeDuplicateOrder(List<NodeLabelMap> orderList) {
        Set<NodeLabelMap> set = new TreeSet<NodeLabelMap>(new Comparator<NodeLabelMap>() {
            @Override
            public int compare(NodeLabelMap a, NodeLabelMap b) {
                return a.getValue1().compareTo(b.getValue1());
            }
        });
        set.addAll(orderList);
        return new ArrayList<NodeLabelMap>(set);
    }


    private List<NodeLabelMap> getChildListMap(String id, List<NodeLabelMap> permissList) {
        List<NodeLabelMap> childList = new ArrayList<>();
        //遍历传入的list
        for (NodeLabelMap permissDto:permissList) {
            //所有菜单的父id与传入的根节点id比较,若相等则为该级菜单的子菜单
            if (!ObjectIsNullUtil.isNullOrEmpty(permissDto.getParentNo()) && permissDto.getParentNo().equals(id)){
                childList.add(permissDto);
            }
        }
        //递归
        for (NodeLabelMap permissDto:childList) {
            permissDto.setChildren(getChildListMap(permissDto.getValue1(),permissList));
        }
        return childList;
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值