java list 转 树型结构

package com.edu.study.normal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class Demo {

    public static void main(String[] args) {
        List<Map<String,Object>> dataList = new ArrayList<Map<String, Object>>();
        setTestData(dataList);
        List<Map<String,Object>> treeNodes = Demo.listTranstoTree(dataList);
        for(Map<String,Object> node : treeNodes) {
            System.out.println(node);
        }
    }
    
    /**
     * 设置测试数据
     * 中国
     *     湖南
     *         邵阳
     *             隆回
     *                 七江
     *                 高平
     *             洞口
     *         岳阳
     *     四川
     *         成都
     *             宜宾
     * 美国
     *     加州
     * @param dataList
     */
    public static void setTestData(List<Map<String,Object>> dataList) {
        Map<String,Object> bean = new HashMap<String,Object>();
        bean.put("id", "hunan");
        bean.put("pid", "zg");
        bean.put("text", "湖南");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "chengdu");
        bean.put("pid", "sichuan");
        bean.put("text", "成都");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "shaoyang");
        bean.put("pid", "hunan");
        bean.put("text", "邵阳");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "zg");
        bean.put("pid", "#");
        bean.put("text", "中国");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "yueyang");
        bean.put("pid", "hunan");
        bean.put("text", "岳阳");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "longhui");
        bean.put("pid", "shaoyang");
        bean.put("text", "隆回");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "mg");
        bean.put("pid", "#");
        bean.put("text", "美国");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "dongkou");
        bean.put("pid", "shaoyang");
        bean.put("text", "洞口");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "qijiang");
        bean.put("pid", "longhui");
        bean.put("text", "七江");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "yibin");
        bean.put("pid", "chengdu");
        bean.put("text", "宜宾");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "sichuan");
        bean.put("pid", "zg");
        bean.put("text", "四川");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "jiazhou");
        bean.put("pid", "mg");
        bean.put("text", "加州");
        dataList.add(bean);
        bean = new HashMap<String,Object>();
        bean.put("id", "gaoping");
        bean.put("pid", "longhui");
        bean.put("text", "高平");
        dataList.add(bean);
    }
    
    /**
     * 列表转为树 数据格式为 id,pid,text;第一层级节点 pid="#"
     * @param dataList
     * @return
     */
    public static List<Map<String,Object>> listTranstoTree(List<Map<String,Object>> dataList) {
        Iterator<Map<String, Object>> itor = dataList.iterator();
        List<Map<String,Object>> treeNodes = new ArrayList<Map<String, Object>>();
        //获取第一级节点 (pid="#")
        while(itor.hasNext()) {
            Map<String,Object> node = itor.next();
            if("#".equals(node.get("pid"))) {
                treeNodes.add(node);
                itor.remove();
            }
        }
        
        Map<String,Boolean> flagMap = new LinkedHashMap<String,Boolean>();
        //设置子节点
        for(Map<String,Object> node:treeNodes) {
            setChildren(node,dataList,flagMap);
        }
        if(dataList.size() > 0) {
            //TODO 还存在未匹配的节点
            System.out.println(dataList);
        }
        return treeNodes;
    }
    
    /**
     * 递归设置子节点
     * @param curNode 当前节点
     * @param dataList 数据列表
     * @param flagMap 标识节点是否存在子节点 
     */
    @SuppressWarnings("unchecked")
    public static void setChildren(Map<String,Object> curNode,List<Map<String,Object>> dataList,Map<String,Boolean> flagMap) {
        Iterator<Map<String, Object>> itor = dataList.iterator();
        String key = curNode.get("id")+"";
        flagMap.putIfAbsent(key, false);//初始化
        Map<String,Object> nextNode;
        List<Map<String,Object>> childList;
        while(itor.hasNext()) {
            //若当前节点存在子节点,再次遍历时,因为dataList已发生改变,遍历器需要重新赋值,否则会触发failfast机制异常。
            if(flagMap.get(key)) {
                itor = dataList.iterator();
                flagMap.put(key, false);//完成一次递归后,就需要重置标识,否则会进入死循环
            }
            //遍历器可能发生变化,需要再次判断,是否有next节点,否则获取next节点时可能报空指针异常
            if(itor.hasNext()) {
                nextNode = itor.next();
                if(curNode.get("id").equals(nextNode.get("pid"))) {
                    childList = (List<Map<String, Object>>) (curNode.containsKey("childList") ? curNode.get("childList") : new ArrayList<Map<String, Object>>());
                    childList.add(nextNode);
                    curNode.put("childList", childList);
                    itor.remove();
                    flagMap.put(key, true);//设置当前节点存在子节点
                    setChildren(nextNode,dataList,flagMap);
                }
            }
        }
    }
}

 

git地址: https://git.lug.ustc.edu.cn/stu/mavendemo.git
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生成树型结构通常可以使用递归算法,以下是一个示例代码: 假设我们有一个如下的路径字符串: ```java String path = "/a/b/c/d"; ``` 我们希望将其换为如下的树型结构: ``` a └── b └── c └── d ``` 可以使用以下的代码实现: ```java import java.util.ArrayList; import java.util.List; public class TreeGenerator { public static void main(String[] args) { String path = "/a/b/c/d"; Node rootNode = generateTree(path); System.out.println(rootNode.toString()); } public static Node generateTree(String path) { String[] pathArray = path.split("/"); Node rootNode = new Node(pathArray[1]); Node currentNode = rootNode; for (int i = 2; i < pathArray.length; i++) { Node childNode = new Node(pathArray[i]); currentNode.addChild(childNode); currentNode = childNode; } return rootNode; } static class Node { private String name; private List<Node> children = new ArrayList<>(); public Node(String name) { this.name = name; } public void addChild(Node child) { children.add(child); } @Override public String toString() { return toString(0); } private String toString(int level) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < level; i++) { sb.append(" "); } sb.append(name).append("\n"); for (Node child : children) { sb.append(child.toString(level + 1)); } return sb.toString(); } } } ``` 该代码会输出以下内容: ``` a b c d ``` 其中,`Node` 类表示树中的节点,`generateTree` 方法用于将路径字符串化为树型结构,`toString` 方法用于将树型结构化为字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值