使用java将横向结构的数据转为树形结构

【飞机专用地址:https://v.tnabors.com/】

今天北京下大雨,公司让居家办公,写完需求觉得没什么意思,然后看了一个别人写的接口,接口功能很简单就是将查询出来的数据展示为树形结构,数据库中的数据结构就是这个样子,每条数据都有一级编码、二级编码、三级编码、四级编码,然后将这四层转换为树形结构。

还有一个是我从网上找个,也是一个转树形结构的例子,这两个还有有点区别的,都记录一下吧平常都是做业务处理代码,感觉好久没写这种代码了,今天尝试写了,特此记录一下。横向结构1

数据库中存储大概是这种转换前:

转换为JSON转换后:

转换后上面是我删除数据后展示的结果,其实数据量有很多,我是为了展示层级关系下面是我思考后写的代码//这是数据库查询结果对应的类,分别与上面数据库截图中的数据字段相对应publicclass CsmpTreeData { 。

privateString csmpTreeId; privateString firstNodeId; privateString firstNodeName; private

String secondNodeId; privateString secondNodeName; privateString thirdNodeId; privateString

thirdNodeName; privateString forthNodeId; privateString forthNodeName; }//这个数据是返回前端的数据结构public

class CloudTreeNode { privateString nodeId; privateString nodeName; privateString level;

privateString parentNodeId; private List children; }//创建了一个工具类,对外提供一个方法,直接讲查询数据的list集合传进行就可以

publicclassTreeUtil{ //为什么要有这个map呢,我的想法是因为从数据库查询出来的结果是横向的结构//我是想在递归的时候根据递归的层级id去判断我我在横向的数据应该获取第几级数据

privatestaticfinal HashMap treeMap = newHashMap<>(); //还有一个问题,这里我为啥要拿两个字段拼接来作为分组条件呢,是因为我在写的过程中发现我虽然获取到了id

//但是name依然不好获取,这里我就直接将两个字段拼接到了一块static { //层级是1,我就应该查询的数据中去getFirstNodeId//层级是2,我就应该查询的数据中去getSecondNodeId

//... treeMap.put(1, (treeData) -> treeData.getFirstNodeId() + "," + treeData.getFirstNodeName()); treeMap.put(

2, (treeData) -> treeData.getSecondNodeId() + "," + treeData.getSecondNodeName()); treeMap.put(

3, (treeData) -> treeData.getThirdNodeId() + "," + treeData.getThirdNodeName()); treeMap.put(

4, (treeData) -> treeData.getForthNodeId() + "," + treeData.getForthNodeName()); } /** * @author

wangpeng * @version 1.0 * @apiNote ,这个方法是外部调用的方法,传入的数据是直接从数据库中查询的数据 * 构建树形结构 * @date

2023/7/31 4:59 下午 * @since JDK1.8 **/publicstaticList buildTreeNode(List

list) { ArrayList cloudTreeNode = new ArrayList<>(); if (CommonUtil.isNotNullList(

list)) { //这里是代表第一层的意思 int i = 1; //通过key获取对应的分组字段,这里是获取getFirstNodeId+"," + treeData.getFirstNodeName()

//说白了就是按一级编码分组 Map firstNode = list.stream().collect(Collectors.groupingBy(getFunction(i)));

for (Map.Entry entry : firstNode.entrySet()) { //将key进行分割,获取一级编码和一级名称

String[] idAndName = StringUtils.split(entry.getKey(), ","); String firstNodeId = idAndName[

超级加密线路:https://av1o.com/

0]; String firstNodeName = idAndName[1]; //这个是所有FirstNodeId等于当前一级编码的集合

List candidateTreeData = entry.getValue(); //创建最外层一级编码对象 CloudTreeNode firstTreeNode =

new CloudTreeNode(); firstTreeNode.setNodeId(firstNodeId); firstTreeNode.setNodeName(firstNodeName);

//设置层级 firstTreeNode.setLevel(i + ""); //构建子节点 firstTreeNode.setChildren(buildTreeNode(candidateTreeData, firstNodeId, i));

//将数据返回 cloudTreeNode.add(firstTreeNode); } } return cloudTreeNode; }

privatestaticList buildTreeNode(List treeData, String parentNodeId, int i) { ArrayList

list = new ArrayList<>(); ++i; //这个方法是一个递归方法,这里的i跟上面方法的意思是一样的,是层级的意思//我们通过层级id去查询map,然后拿到get第几层那个方法

Function function = getFunction(i); //没有层级后返nullif (Objects.isNull(function

)) returnnull; //这里跟一级一样,这里又是分组,假如是二级的话,则通过getSecondNodeId等来获取二级编码数据 Map nodes = treeData.stream().collect(Collectors.groupingBy(

function)); if (CommonUtil.checkMap(nodes)) { for (Map.Entry entry : nodes.entrySet()) {

//获取当前级别的nodeId String[] idAndName = StringUtils.split(entry.getKey(), ","); String nodeId = idAndName[

0]; String nodeName = idAndName[1]; //这里是当前级别的数据List candidateTreeData = entry.getValue(); CloudTreeNode cloudTreeNode =

new CloudTreeNode(); cloudTreeNode.setParentNodeId(parentNodeId); cloudTreeNode.setNodeId(nodeId); cloudTreeNode.setNodeName(nodeName);

//设置级别 cloudTreeNode.setLevel(i + ""); //递归调用,设置层级 cloudTreeNode.setChildren(buildTreeNode(candidateTreeData, nodeId, i));

list.add(cloudTreeNode); } } returnlist; } //这里是从map中获取对应的方法private

staticFunction getFunction(Integer currentId){ return treeMap.get(currentId); } }

˙横向结构2转换前:

转换后:

publicclass ProvinceTreeData { privateString id; privateString pid; private List children;

privateString name; }// list 是从数据库请求回来的数据// 构建前端所需要树publicstaticList buildProvinceTree(

List list){ // 获取根节点List root = list.stream().filter(item -> "0"

.equals(item.getPid())).collect(Collectors.toList()); // 根据pid进行分组 Map provinceTreeMap =

list.stream().collect(Collectors.groupingBy(ProvinceTreeData::getPid)); //先是拿根节点进行遍历 recursionFnTree(root,provinceTreeMap);

return root; } //当前是递归方法publicstatic void recursionFnTree(List list, Map

> provinceTreeMap){ for (ProvinceTreeData provinceTree: list) { //根据当前节点id,从provinceTreeMap中获取对应的子节点,因为provinceTreeMap中的key都是父节点

List childList = provinceTreeMap.get(provinceTree.getId()); //将查询的子节点赋值 provinceTree.setChildren(childList);

if (null != childList && 0

上面两种树形结构的原始数据还是有些差别的,对于这两种数据,以上都是我思考后的想法,对于这两个功能,大家有什么好的想法吗?

vpn官方地址:https://www.sandrakurvits.com/

 分享

本文由网络整理 © 版权归原作者所有

  •  主题颜色

    • 橘色
    • 绿色
    • 蓝色
    • 粉色
    • 红色
    • 金色
  • 扫码用手机访问

本站只提供WEB页面服务,本站不存储、不制作任何视频,不承担任何由于内容的合法性及健康性所引起的争议和法律责任。

若本站收录内容侵犯了您的权益,请附说明联系邮箱,本站将第一时间处理。

© 2024 www.a5fe.com  E-Mail:TG客服:https://t.me/sjkxswkf_bot  

观看记录