“树形List“与“扁平List“互转(Java实现)

Java中平铺列表(List)与树形(Tree)结构的互转 至此,递归和非递归分别实现listtotree和treetolist已完成,实现比较仓促,有很多细节处未处理好,希望看到的小伙伴及时指出,不胜感激。另外,机智的你,有其它更好的方法,实现转换吗?欢迎留言分享,码海无涯,共同进步。httpshttps。... 阅读详情

背景:在平时的开发中,我们时常会遇到下列场景

  1. 公司的组织架构的数据存储与展示
  2. 文件夹层级的数据存储与展示
  3. 评论系统中,父评论与诸多子评论的数据存储与展示
  4. ......

对于这种有层级的结构化数据,就像是一棵树一样。在关系型数据库中,通常将一个个的节点信息存储到表中,通过一个字段(例如,pid),指向其父节点。而在数据展示的时候,我们又希望它是呈现层级的,例如:

id  name        pid
1   总公司       -1
2   上海分公司    1
3   浙江分公司    1
4   闵行区分公司  2
5   嘉兴分公司    3

{
    "id": 1,
    "name": "总公司",
    "pid": -1,
    "branch":
    [
        {
            "id": 2,
            "name": "上海分公司",
            "pid": 1,
            "branch":
            [
                {
                    "id": 4,
                    "name": "闵行区分公司",
                    "pid": 2,
                    "branch":
                    []
                }
            ]
        },
        {
            "id": 3,
            "name": "浙江分公司",
            "pid": 1,
            "branch":
            [
                {
                    "id": 5,
                    "name": "嘉兴分公司",
                    "pid": 3,
                    "branch":
                    []
                }
            ]
        }
    ]
}

所以,本文的主要内容就是提供几种方案,实现这两类数据的转换方式。

内容导览

存储树的表结构

扁平List转树形List

双层for

递归

转换为Map

栈

树形List转扁平List

递归

栈


存储树的表结构

如何在一张数据库表中表示一颗树结构中的所有节点信息,这里有一个示例:

DROP TABLE IF EXISTS zj_city;
CREATE TABLE zj_city (
    id BIGINT NOT NULL AUTO_INCREMENT,
    name VARCHAR(50) COMMENT '节点名称',
    pid int NOT NULL COMMENT '父节点',

    create_time DATETIME DEFAULT now() COMMENT '创建时间: 年-月-日 时:分:秒',
    update_time DATETIME DEFAULT now() ON UPDATE now() COMMENT '更新时间',
    is_deleted BIT DEFAULT 0 COMMENT '是否删除:0-false-未删除;1-true-已删除',
    PRIMARY KEY (id)
)COMMENT '浙江城市';

INSERT INTO zj_city(name, pid) VALUES
('浙江省',0),
('金华市',1),
('嘉兴市',1),
('杭州市',1),
('宁波市',1);

INSERT INTO zj_city(name, pid) VALUES
('下城区',4),
('钱塘区',4),
('西湖区',4),
('上城区',4);

INSERT INTO zj_city(name, pid) VALUES
('南湖区',3),
('秀洲区',3),
('桐乡市',3),
('平湖市',3),
('海宁市',3);

INSERT INTO zj_city(name, pid) VALUES
('梧桐街道',12),
('凤鸣街道',12),
('龙翔街道',12),
('崇福镇',12),
('乌镇镇',12),
('高桥镇',12),
('河山镇',12),
('濮院镇',12);

SELECT * from zj_city;

扁平List转树形List

应用场景

  • 公司组织结构
  • 省市级
  • 评论系统中,父评论与诸多子评论
  • 其他层级展示的数据

双层for

主要思想:外层循环-找父节点;内层循环-找子节点;因为每个元素都会找一遍,所有最终得到完整的树

import com.alibaba.fastjson.JSON;
import com.ks.boot.entity.CityEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

public class TreeListDemo {
    List<CityEntity> cityEntities;
    /**
     * id  name  pid
     * 1   浙江   0
     * 2   杭州   1
     * 3   嘉兴   1
     * 4   南湖   3
     * 5   桐乡   3
     * 6   余杭   2
     * 7   西湖   2
     * 8   云南   0
     * 9   昆明   8
     * 10  昭通   8
     */
    @BeforeEach
    public void init() {
        cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" +
                "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" +
                "{\"id\":3,\"name\":\"嘉兴\",\"pid\":1},\n" +
                "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" +
                "{\"id\":5,\"name\":\"桐乡\",\"pid\":3},\n" +
                "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" +
                "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" +
                "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" +
                "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" +
                "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class);
    }

    @Test
    public void testList2Tree() {
        List<CityEntity> resultTree = list2Tree(this.cityEntities);
        System.out.println(JSON.toJSONString(resultTree));
    }

    /**
     * 双层for,List转Tree
     * 主要思想:外层循环-找父节点;内层循环-找子节点;因为每个元素都会找一遍,所有最终得到完整的树
     * 时间复杂度:N^2;空间复杂度:N
     */
    public List<CityEntity> list2Tree(List<CityEntity> cityEntities) {
        List<CityEntity> resultCities = new ArrayList<>();
        for (CityEntity city : cityEntities) {
            if(0 == city.getPid()) { //根节点、顶级节点,直接放入最终返回结果的List
                resultCities.add(city);
            }
            for (CityEntity curCity : cityEntities) { //根据当前city找它的子节点
                if(city.getId().equals(curCity.getPid())) {
                    if(city.getSubCityList() == null) { //还没有任何子节点,new一个空的放进去
                        city.setSubCityList(new ArrayList<>());
                    }
                    city.getSubCityList().add(curCity);
                }
            }
        }

        return resultCities;
    }
}

public class CityEntity {
    private Long id;
    private String name;
    private Long pid;

    private List<CityEntity> subCityList;

    getter/setter
}

递归

主要思想:获取所有根节点、顶级节点,再从List中查找根节点的子节点;

import com.alibaba.fastjson.JSON;
import com.ks.boot.entity.CityEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

public class TreeListDemo {
    List<CityEntity> cityEntities;
    /**
     * id  name  pid
     * 1   浙江   0
     * 2   杭州   1
     * 3   嘉兴   1
     * 4   南湖   3
     * 5   桐乡   3
     * 6   余杭   2
     * 7   西湖   2
     * 8   云南   0
     * 9   昆明   8
     * 10  昭通   8
     */
    @BeforeEach
    public void init() {
        cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" +
                "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" +
                "{\"id\":3,\"name\":\"嘉兴\",\"pid\":1},\n" +
                "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" +
                "{\"id\":5,\"name\":\"桐乡\",\"pid\":3},\n" +
                "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" +
                "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" +
                "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" +
                "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" +
                "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class);
    }

    /**
     * 递归,List转Tree
     * 主要思想:获取所有根节点、顶级节点,再从List中查找根节点的子节点;
     * 时间复杂度:N*(1+N)/2,O(N^2),因为递归方法中,最好是List的第一元素就是要找的子节点,最坏是
     * List的最后一个元素是子节点
     */
    @Test
    public void testList2Tree() {
        List<CityEntity> resultCities = new ArrayList<>();
        for (CityEntity city : cityEntities) {
            if(0 == city.getPid()) { //获取所有根节点、顶级节点,再根据根节点进行递归
                CityEntity topCity = findChild(cityEntities, city); //此时的topCity已经包含它的所有子节点
                resultCities.add(topCity);
            }
        }

        System.out.println(JSON.toJSONString(resultCities));
    }

    /**
     *
     * @param cityEntities 在那个里面找
     * @param curCity 找谁的子节点
     * @return curCity的子节点
     */
    public CityEntity findChild(List<CityEntity> cityEntities, CityEntity curCity) {
        for (CityEntity city : cityEntities) {
            if(curCity.getId().equals(city.getPid())) {
                if(null == curCity.getSubCityList()) {
                    curCity.setSubCityList(new ArrayList<>());
                }
                CityEntity subChild = findChild(cityEntities, city); //每次递归,都从头开始查找有没有city的子节点
                curCity.getSubCityList().add(subChild);
            }
        }
        return curCity;
    }

}

public class CityEntity {
    private Long id;
    private String name;
    private Long pid;

    private List<CityEntity> subCityList;

    getter/setter
}

转换为Map

主要思想:

  • 在双层for的解法中,由于内层for也需要遍历以便List,造成时间复杂度上身为平方级
  • 如果内层for不需要遍历完整的List,而是事先预处理到Map中,寻找时直接从Map中获取,则时间复杂度降为LogN
import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TreeListDemo {
    List<CityEntity> cityEntities;
    /**
     * id  name  pid
     * 1   浙江   0
     * 2   杭州   1
     * 3   嘉兴   1
     * 4   南湖   3
     * 5   桐乡   3
     * 6   余杭   2
     * 7   西湖   2
     * 8   云南   0
     * 9   昆明   8
     * 10  昭通   8
     */
    @BeforeEach
    public void init() {
        cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" +
                "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" +
                "{\"id\":3,\"name\":\"嘉兴\",\"pid\":1},\n" +
                "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" +
                "{\"id\":5,\"name\":\"桐乡\",\"pid\":3},\n" +
                "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" +
                "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" +
                "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" +
                "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" +
                "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class);
    }

    /**
     * 在双层for的解法中,由于内层for也需要遍历以便List,造成时间复杂度上身为平方级
     * 如果内层for不需要遍历完整的List,而是事先预处理到Map中,寻找时直接从Map中获取,则时间复杂度降为LogN
     */
    @Test
    public void list2tree() {
        //收集每个PID下的节点为Map
        Map<Long, List<CityEntity>> cityMapByPid = cityEntities.stream().collect(Collectors.groupingBy(CityEntity::getPid));

        List<CityEntity> resultCityList = new ArrayList<>();
        for (CityEntity city : cityEntities) {
            if(0 == city.getPid()) { //根节点、顶点
                resultCityList.add(city);
            }

            List<CityEntity> citiesByPid = cityMapByPid.get(city.getId());
            if(null != citiesByPid && citiesByPid.size() > 0) { //有子节点
                if(null == city.getSubCityList()) {
                    city.setSubCityList(new ArrayList<>());
                }
                city.getSubCityList().addAll(citiesByPid); //塞入
            }
        }

        System.out.println(JSON.toJSONString(resultCityList));
    }

    /**
     * 简化写法:在收集到Map时,对于没有子节点的节点,创建一个空的塞入到Map中
     */
    @Test
    public void list2tree4Simple() {
        List<CityEntity> resultCityList = new ArrayList<>();

        //保存每个PID下的子节点
        Map<Long, List<CityEntity>> cityMapByPid = new HashMap<>();
        for (CityEntity city : cityEntities) { //收集每个PID下的子节点
            //获取当前PID对应的子节点List,如果没有则创建一个空的List塞入
            //这个设计得很巧妙
            List<CityEntity> children = cityMapByPid.getOrDefault(city.getPid(), new ArrayList<>());
            children.add(city); //插入当前元素
            cityMapByPid.put(city.getPid(), children);
        }

        for (CityEntity city : cityEntities) {
            if(0 == city.getPid()) { //根节点、顶点
                resultCityList.add(city);
            }
            city.setSubCityList(cityMapByPid.get(city.getId()));
        }

        System.out.println(JSON.toJSONString(resultCityList));
    }
}

栈

主要思想

  • 收集根节点、顶级节点,存入resultList,并且压栈
  • 循环出栈,栈元素Cur
    • 找Cur的所有子元素为child
    • 如果child不为空,则再压入栈中。这一步的目的是,再一次找child的子元素
import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

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

public class TreeListDemo {
    List<CityEntity> cityEntities;
    /**
     * id  name  pid
     * 1   浙江   0
     * 2   杭州   1
     * 3   嘉兴   1
     * 4   南湖   3
     * 5   桐乡   3
     * 6   余杭   2
     * 7   西湖   2
     * 8   云南   0
     * 9   昆明   8
     * 10  昭通   8
     */
    @BeforeEach
    public void init() {
        cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" +
                "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" +
                "{\"id\":3,\"name\":\"嘉兴\",\"pid\":1},\n" +
                "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" +
                "{\"id\":5,\"name\":\"桐乡\",\"pid\":3},\n" +
                "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" +
                "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" +
                "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" +
                "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" +
                "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class);
    }

    /**
     * 主要思想:
     *  收集根节点、顶级节点,存入resultList,并且压栈
     *  循环出栈,栈元素Cur
     *      找Cur的所有子元素为child
     *      如果child不为空,则再压入栈中。这一步的目的是,再一次找child的子元素
     * 时间复杂度:N(过滤出所有跟节点) + 常数(出栈) * N(遍历List找当前节点的子元素)
     */
    @Test
    public void list2tree() {
        List<CityEntity> resultCityList = new ArrayList<>();

        Stack<CityEntity> stack = new Stack<>();
        resultCityList = cityEntities.stream().filter(ele -> 0 == ele.getPid()).collect(Collectors.toList());
        stack.addAll(resultCityList); //根节点、顶点入栈

        while(!stack.isEmpty()) {
            CityEntity curCity = stack.pop();
            List<CityEntity> child = cityEntities.stream().filter(ele -> curCity.getId().equals(ele.getPid())).collect(Collectors.toList());
            if(!child.isEmpty()) { //这一步处理的原因是:当没有子元素,不显示该个字段。流处理后没有元素只会返回空List,不会返回null
                curCity.setSubCityList(child);
            }
            if(!child.isEmpty()) {
                stack.addAll(child);
            }
        }

        System.out.println(JSON.toJSONString(resultCityList));
    }
}

树形List转扁平List

递归

主要思想:遍历树节点,一个树节点如果有子树,则再次递归此子树,直到没有子树为止

import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * id  name  pid
 * 1   浙江   0
 * 2   杭州   1
 * 3   嘉兴   1
 * 4   南湖   3
 * 5   桐乡   3
 * 6   余杭   2
 * 7   西湖   2
 * 8   云南   0
 * 9   昆明   8
 * 10  昭通   8
 */
public class ListTreeDemo {
    List<CityEntity> treeList;

    @BeforeEach
    public void init() {
        treeList = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0,\"subCityList\":[" +
                "{\"id\":2,\"name\":\"杭州\",\"pid\":1,\"subCityList\":[{\"id\":6,\"name\":\"余杭\",\"pid\":2},{\"id\":7,\"name\":\"西湖\",\"pid\":2}]}," +
                "{\"id\":3,\"name\":\"嘉兴\",\"pid\":1,\"subCityList\":[{\"id\":4,\"name\":\"南湖\",\"pid\":3},{\"id\":5,\"name\":\"桐乡\",\"pid\":3}]}]}," +
                "{\"id\":8,\"name\":\"云南\",\"pid\":0,\"subCityList\":[{\"id\":9,\"name\":\"昆明\",\"pid\":8},{\"id\":10,\"name\":\"昭通\",\"pid\":8}]}]", CityEntity.class);
    }

    @Test
    public void tree2list() {
        List<CityEntity> resList = new ArrayList<>();

        //这一层for的目的是:遍历根节点
        for (CityEntity city : treeList) {
            reversion(city,resList);
        }
        System.out.println(JSON.toJSONString(resList));
    }
    public void reversion(CityEntity curNode, List<CityEntity> resList) {
        resList.add(beanCopy(curNode));

        List<CityEntity> subCityList = curNode.getSubCityList();
        if(subCityList != null && !subCityList.isEmpty()) {
            for (CityEntity city : subCityList) { //递归寻找子节点的子节点们
                reversion(city, resList);
            }
        }
        
        //递归的出口就是subCityList为null或者empty
    }

    private CityEntity beanCopy(CityEntity source) {
        CityEntity res = new CityEntity();
        res.setId(source.getId());
        res.setName(source.getName());
        res.setPid(source.getPid());
        return res;
    }
}

栈

主要思想

  1. 依次遍历树形List,当前节点为Cur
    1. 将Cur收集到某个存储结果的List
    2. 如果Cur有子树,压入某个栈中
  2. 依次弹出栈元素,当前弹出的元素为StackSubTree
    1. 如果StackSubTree还有子树,继续压栈
    2. 如果StackSubTree没有子树,则放入结果List
import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * id  name  pid
 * 1   浙江   0
 * 2   杭州   1
 * 3   嘉兴   1
 * 4   南湖   3
 * 5   桐乡   3
 * 6   余杭   2
 * 7   西湖   2
 * 8   云南   0
 * 9   昆明   8
 * 10  昭通   8
 */
public class ListTreeDemo {
    List<CityEntity> treeList;

    @BeforeEach
    public void init() {
        treeList = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0,\"subCityList\":[" +
                "{\"id\":2,\"name\":\"杭州\",\"pid\":1,\"subCityList\":[{\"id\":6,\"name\":\"余杭\",\"pid\":2},{\"id\":7,\"name\":\"西湖\",\"pid\":2}]}," +
                "{\"id\":3,\"name\":\"嘉兴\",\"pid\":1,\"subCityList\":[{\"id\":4,\"name\":\"南湖\",\"pid\":3},{\"id\":5,\"name\":\"桐乡\",\"pid\":3}]}]}," +
                "{\"id\":8,\"name\":\"云南\",\"pid\":0,\"subCityList\":[{\"id\":9,\"name\":\"昆明\",\"pid\":8},{\"id\":10,\"name\":\"昭通\",\"pid\":8}]}]", CityEntity.class);
    }

    /**
     * 1. 依次遍历树形List,当前节点为Cur
     *   a) 将Cur收集到某个存储结果的List
     *   b) 如果Cur有子树,压入某个栈中
     * 2. 依次弹出栈元素,当前弹出的元素为StackSubTree
     *   a) 如果StackSubTree还有子树,继续压栈
     *   b) 如果StackSubTree没有子树,则放入结果List
     */
    @Test
    public void tree2list() {
        List<CityEntity> resList = new ArrayList<>();

        Stack<List<CityEntity>> stack = new Stack<>();

        for (CityEntity curCity : treeList) {
            resList.add(beanCopy(curCity));
            if (curCity.getSubCityList() != null && !curCity.getSubCityList().isEmpty()) {
                stack.push(curCity.getSubCityList());
            }
        }

        while (!stack.isEmpty()) {
            List<CityEntity> subTree = stack.pop();
            for (CityEntity city : subTree) {
                if (city.getSubCityList() != null && !city.getSubCityList().isEmpty()) {
                    stack.push(city.getSubCityList());
                } else {
                    resList.add(beanCopy(city));
                }
            }
        }

        System.out.println(JSON.toJSONString(resList));
    }

    private CityEntity beanCopy(CityEntity source) {
        CityEntity res = new CityEntity();
        res.setId(source.getId());
        res.setName(source.getName());
        res.setPid(source.getPid());
        return res;
    }
}

JAVA树状List数据转普通List JAVA树状List转普通List 阅读详情

相关推荐

Java List对象转List方法】——实现集合类型转换的高效方法

然后,我们通过在LinkedList的构造函数中传入"sourceList"来创建了一个新的LinkedList对象"targetList",实现了从ArrayList到LinkedList的转换。假设我们有一个名为"sourceList"的ArrayList对象,我们希望将其转换为LinkedList类型的集合。综上所述,通过使用Java提供的不同方法,我们可以高效地实现List对象到其他集合类型的转换。选择适合具体场景的方法,可以提高代码的可读性和执行效率,从而优化程序的性能。(本文总字数:361)

CyberByte的博客 2822

java 处理树形结构 树形转为list list转为树形

java 处理树形结构 树形转为list list转为树形

doris的博客 5492

Java中List到树形结构转换的工具类实现

在计算机科学中,树形结构是一种非常重要的非线性数据结构,它通过分层的节点来模拟具有层级关系的数据。树由节点(node)和连接节点之间的边(edge)组成,每个节点都有一个值(称为节点值或节点数据)和一个或多个指向下级节点的指针。树的最顶层节点通常被称为根节点(root),而没有任何子节点的节点被称为叶子节点(leaf)。在深入理解树之前,我们先熟悉一些基础术语:节点(Node):树中的每个元素称为节点,每个节点都有一个值和指向子节点的引用。边(Edge):节点之间的连接称为边。

weixin_31974443的博客 1241

java实现将树形结构平铺为List列表

java实现将树形结构转为列表

xuwenze的博客 4463

ESP32C3的I2S接口详解:以驱动PCM5102A为例,避开时序与配置的那些坑

本文深入解析ESP32C3的I2S接口驱动PCM5102A DAC的完整解决方案,涵盖时序对齐、PCB优化和寄存器级配置。通过实际案例分享时钟树分析、信号完整性设计和底层调试技巧,帮助开发者避开常见陷阱,实现高质量音频输出。重点探讨了I2S协议栈、电源滤波优化及DMA传输异常处理等关键技术要点。

weixin_30254435的博客 298

数学建模 种群竞争模型 学习笔记

模型背景 应用场景 种群竞争模型 例如 s1=0.5,则表示对于供养甲的资源来讲,单位数量的乙的消耗为单位数量的甲的0.5倍,即表示乙对于该资源的占有能力是甲的0.5倍(即竞争力弱) 仿真结果及分析 (1)设置自然增长率 r1=r2=1 (2)改变自然增长率 r1=r2=0.3 (3)修改甲和乙的最大容量 n1=10000, n2=100 (4)修改甲和乙的初始数量 x1=10, x...

Test_tju的博客 2028

扁平List转树形List

【代码】扁平List转树形List。

m0_49341808的博客 411

ThingsBoard实战指南:RPC命令下发与设备交互详解

本文深入解析了ThingsBoard平台中RPC命令下发的核心机制与实战应用。通过对比客户端与服务端RPC模式,详细阐述了从仪表盘控件配置到设备端Python代码响应的完整双向交互流程,并提供了常见问题排查与进阶优化技巧,帮助开发者构建可靠、实时的物联网设备控制系统。

weixin_29168153的博客 211

java_扁平<--->树转换的思路和方法参考

java扁平转树形和树形转扁平的思路分享,利用已学过的知识,巧用集合 。

qq_64646478的博客 765

从“盲控”到“预见”:聊聊永磁同步电机负载观测器(PMSM Load Observer)如何让控制更丝滑

本文深入探讨了永磁同步电机负载观测器(PMSM Load Observer)如何通过前馈补偿和转动惯量辨识技术实现智能抗扰控制。从传统‘盲控’到预见性调节,负载观测器显著减少转速波动和能耗,提升系统响应速度。文章详细解析了观测器算法架构、工程调参技巧及前沿发展趋势,为电机控制领域提供实用解决方案。

weixin_33737774的博客 406

STM32G0定时器中断实战:HAL库配置TIM2实现精准1秒LED闪烁(附完整代码)

本文深入解析了STM32G0系列微控制器中定时器中断的配置与应用,重点介绍了如何使用HAL库配置TIM2实现精准的1秒LED闪烁。通过详细讲解时钟树分析、预分频系数与自动重装载寄存器的计算原理,并结合CubeMX图形化配置与完整代码示例,帮助开发者从底层理解定时器工作机制,掌握可复用的工程化配置方法。

weixin_29194817的博客 253

list转树形结构

先上效果 //实体类 class TreeNode{ String id; String name; String pId; List<TreeNode> childRen=new ArrayList<>(); public String getId() { return id; } public void setId(String id) { ...

臭小子的博客 531

深度强化学习-D3QN算法原理与代码

Dueling Double Deep Q Network(D3QN)算法结合了Double DQN和Dueling DQN算法的思想,进一步提升了算法的性能。如果对Doubel DQN和Dueling DQN算法还不太了解的话,可以参考我的这两篇博文:深度强化学习-Doubel DQN算法原理与代码和深度强化学习-Dueling DQN算法原理与代码,分别详细讲述了这两个算法的原理以及代码实现。本文就带领大家了解一下D3QN算法,代码链接见下方。 代码:https://github.com/indigo

weixin_46133643的博客 2万+

Java 通用树形结构构建与解析工具类解析

本文提出了一种高效的树形结构双向转换算法,实现了扁平列表(List)与嵌套树形(Tree)结构的相互转换。核心算法采用HashMap空间换时间策略,将List转Tree的时间复杂度优化至O(n)。通过两次遍历:第一次构建节点映射表并确定根节点,第二次建立父子引用关系。Tree转List则采用递归深度优先搜索实现。测试验证了算法的正确性,展示了包含多级节点的转换结果。该方案适用于中等规模数据集的层级关系处理,在部门结构、菜单权限等场景具有实用价值,兼顾了时间效率与代码可读性。

xiaojianhx的专栏 217

华为OD机试真题 新系统 - 8位LED控制器 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 1975

T型三电平逆变器中点电位平衡详解

T型三电平逆变器(T-type Three-Level Inverter)是一种高效的多电平拓扑,相比传统NPC(Neutral Point Clamped)三电平逆变器,具有更低的开关损耗、更高效率和更简单的结构,尤其适用于中功率应用(如光伏逆变器、风电变换器和工业驱动)。(T-type Three-Level Inverter)中的应用已成为当前中高压功率变换领域(如光伏逆变器、储能PCS、电动汽车充电桩、风电并网和工业驱动)的热门方案。针对 T型逆变器,类似 NPC 的零序注入法适用。

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 545

java list转tree实现树状菜单

有时候我们从数据库中读取出了一个表的数据,比如存储的是中国的省市县的ID、名称与父节点ID,读出来的数据并不是前台想要的(当然现在好多tree库可以使用,不要拆台,最起码不好看是吧==),这个时候我们要想法处理一下都出来的list,将它变为一个树。  比如直接查出来是左边的数据,我们要的效果是右边的数据 新建实体类: public class SysDept { private ...

我惠依旧的博客 8090

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

树形结构list构建(树形实体)

树形结构list构建(树形实体) 树形sql查出是按树形顺序排列的list(结果集),正真要形成树形结构的对象还要组织下(Tree(自包含结构)),   在设计树形数据的时候根节点的标志比如id=-1,或他的parentId=null,这样可以由这个根连接下去 树形实体结构的构建依赖于树形顺序的sql,以方便顺序组织(再利用迭代),   同理树形html的展现也是依赖树形顺序的sql,

yuhui666666的博客 2138

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

树形结构数据生成树

package test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; /** * * @author yg */ @SuppressWarnings(...

阳光 726

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

List转树形结构后返给前端

/** * 使用递归方法建树 * @return */ public static List<OrganizationTreeVo> buildByRecursive(List<OrganizationTreeVo> organizationTreeVos) { List<OrganizationTreeVo> trees = new ArrayList<OrganizationTreeVo>(); for (OrganizationT.

anli1990的博客 348

【JAVA】List<Object>类型构建树结构数据

JAVA中使用递归构建List类型的梳妆结构数据

SmallCat0912的博客 1088

将集合转换成树形结构

本文探讨了将扁平List转换为树形结构的三种方案。基础递归方案(O(n²))逻辑简单但性能差;推荐使用Map索引法(O(n)),通过空间换时间提升效率;Java8 Stream方案简洁但性能与递归类似。实战中建议采用Map索引法,并提供了通用工具类实现,支持泛型节点和自定义字段。该方案适用于菜单管理、组织架构等需要树形数据展示的场景,能有效处理大数据量情况。

huangpf_vcx 919

embassy-net-ppp 串口 PPP 驱动演进全解析:从 0.1.0 首发到 0.3.0 的版本脉络与实现原理

embassy-net-ppp 是 Rust 异步嵌入式框架 Embassy 生态中,将 PPP(Point-to-Point Protocol,点对点协议)over Serial 接入 [embassy-net](https://link.gitcode.com/i/573c5f3978c874a2df721c62397b488c) 网络栈的官方驱动。本文以仓库内 [embassy-net-pp

gitblog_00593的博客 217

基于树形结构与POI的Java多级表头Excel导出方案详解

在Java企业级应用开发中,数据导出是常见的功能需求,而Apache POI作为处理Office文档的核心库,其灵活性与复杂性并存。理解其底层原理,关键在于掌握如何将数据结构(如列表、树)映射到Excel的单元格与行列坐标上。这种映射能力对于实现动态、可配置的报表导出具有重要技术价值,尤其在需要展示复杂层级关系的业务场景中,如财务报表、绩效考核表等。通过构建树形结构模型来描述表头层级,并利用递归算法自动计算单元格的合并范围,可以将表头的定义与渲染逻辑解耦,从而提升代码的可维护性和扩展性。本文聚焦于利用POI

cuml0912的博客 567

Java List 生成 树(增强版)

  Java List 生成 树:http://ysj5125094.iteye.com/blog/2283159   maven pom.xml &lt;dependency&gt; &lt;groupId&gt;commons-collections&lt;/groupId&gt; &lt;artifactId&gt;commons-collections&lt;/artif...

ysj5125094的专栏 1746
上一篇: Nginx基础03:配置文件nginx.conf(Part2)
下一篇: 一款简单易用的远程日志查看器,可实时查看云服务器上的日志数据
ALGO阿狗
博客等级 码龄9年 64粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值