stream流拼接树形结构

package cn.e4j.modular.iqs.utils;

import cn.e4j.core.dto.impl.Dto;
import cn.e4j.modular.iqs.entity.FrsadT;
import cn.e4j.modular.iqs.entity.TreeNode;
import cn.e4j.modular.iqs.service.impl.Frs04ServiceImpl;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component
public class BuildTreeUtil {

    @Resource
    private Frs04ServiceImpl frs04Service;

    public List<TreeNode> getFRSADTTreeList(Dto inDto) {
        List<FrsadT> parentId = frs04Service.getParentId(inDto);
        List<TreeNode> nodes = new ArrayList<>();
        List<FrsadT> list = frs04Service.getList();
        list.forEach(item -> {
            TreeNode treeNode = new TreeNode(item.getAD001(), item.getAD002(), item.getAD004(), item.getAD004());
            nodes.add(treeNode);
        });
        if (parentId != null) {
            return buildTree(nodes, parentId.get(0).getParent_code());
        }
        return null;
    }

    public static List<TreeNode> buildTree(List<TreeNode> treeNodes, String parentId) {
        List<TreeNode> treeList = new ArrayList<>();

        treeNodes.stream()
                .filter(node -> parentId.equals(node.getParentId()))
                .peek(treeList::add)
                .forEach(root -> addChildren(root, treeNodes));

        return treeList;
    }

    private static void addChildren(TreeNode treeNode, List<TreeNode> treeNodes) {
        treeNodes.stream()
                .filter(node -> treeNode.getId().equals(node.getParentId()))
                .peek(treeNode.getChildren()::add)
                .forEach(child -> addChildren(child, treeNodes));
    }
}
### Java 实现树形结构父类节点拼接 在Java中实现树形结构的父类节点拼接可以通过多种方式完成,其中一种常见的方式是通过递归算法来查找并连接所有的子节点。另一种非递归的方法则是利用哈希表(`HashMap`)来进行父子关系映射。 #### 方法一:基于递归的解决方案 这种方法适用于较小规模的数据集,在每次迭代过程中都会尝试找到当前节点下的所有直接子节点,并继续向下一层深入直到达到叶节点为止。下面是一个简单的例子: ```java public class TreeNode { private Integer id; private String name; private List<TreeNode> children; public TreeNode(Integer id, String name) { this.id = id; this.name = name; this.children = new ArrayList<>(); } // Getters and Setters... } // 构建树函数 private void buildTree(List<TreeNode> nodeList, Map<Integer, TreeNode> nodeMap){ for (TreeNode node : nodeList) { Integer parentId = getParentId(node); // 获取该节点对应的父ID逻辑需自行补充 if(parentId != null && !parentId.equals(0)){ TreeNode parentNode = nodeMap.get(parentId); if(parentNode!=null){ parentNode.getChildren().add(node); } }else{ rootNodes.add(node); // 如果没有父节点,则认为它是根节点之一 } nodeMap.put(node.getId(),node); } } ``` 此代码片段展示了如何创建一个基本的树状对象模型以及初步建立父子关联的过程[^1]。 #### 方法二:使用 `HashMap` 进行优化 对于大规模数据集来说,频繁调用数据库查询可能会导致性能瓶颈。因此可以先一次性加载全部记录至内存中的集合里,再借助于 `HashMap` 来快速定位每一个可能成为其他节点父亲的角色。这样做的好处是可以减少不必要的重复访问操作次数,提高整体效率。 ```java import java.util.*; class NodeWithParentIds extends TreeNode { private StringBuilder parentIds; @Override public String toString() { return "Node{" + getId() +" parents=" + parentIds.toString()+ '}'; } public static List<NodeWithParentIds> convertToTreeStructure(List<Map<String,Object>> rawData){ HashMap<Long,List<NodeWithParentIds>> map=new HashMap<>(); HashSet<Long> allIdsSet=rawData.stream().map(item->Long.parseLong(String.valueOf(item.get("id")))).collect(Collectors.toCollection(HashSet::new)); List<NodeWithParentIds> resultTreesList=new LinkedList<>(); for(Map<String , Object> record:rawData){ Long currentId=(long)(int)record.get("id"); long pid=((Double)record.getOrDefault("pid",0d)).longValue(); NodeWithParentIds currentNode=null; if(map.containsKey(currentId)){ currentNode=map.get(currentId).get(0); }else{ currentNode=new NodeWithParentIds((Integer)record.get("id"),String.valueOf(record.get("name"))); map.computeIfAbsent(currentId,k->{return new ArrayList<>();}).add(currentNode); if(pid==0||!allIdsSet.contains(pid))resultTreesList.add(currentNode);//如果是顶级节点就加入最终列表 } if(!currentId.equals(pid)&&pid!=0&&allIdsSet.contains(pid)){ NodeWithParentIds fatherNode=map.get(pid).stream().findFirst().orElse(null); if(fatherNode!=null){ fatherNode.addChild(currentNode); // 更新parentIds字段 if(fatherNode.getParentIds()!=null&&!fatherNode.getParentIds().isEmpty()) currentNode.setParentIds(new StringBuilder(fatherNode.getParentIds()).append(",").append(pid)); else currentNode.setParentIds(new StringBuilder().append(pid)); map.computeIfPresent(pid,(k,v)->{v.remove(fatherNode);if(v.isEmpty())map.remove(k);return v;} ); } } } return resultTreesList; } public void setParentIds(StringBuilder parentIds) {this.parentIds = parentIds;} public StringBuilder getParentIds(){return parentIds;} // Other methods omitted. } ``` 这段程序实现了更复杂的场景——不仅建立了树的关系链路,还额外维护了一个字符串形式的祖先路径(`parentIds`)以便后续追踪每个节点在整个层次体系里的位置信息[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值