• 实现pathListToMap, 能够将输入的pathList转化为具有层级结构的map类型


    实现pathListToMap, 能够将输入的pathList转化为具有层级结构的map类型

    申明

    首先说明一下,这是一道面试题。介于时间关系这道题只能算是解决了一半。

    一、问题描述

            //实现pathListToMap, 能够将输入的pathList转化为具有层级结构的map类型
            //输入
            List<String> pathList = Arrays.asList(
                    "/etc/hosts",
                    "/etc/kubernetes/ssl/certs",
                    "/root"
            );
            //输出
    /**
             {
                "etc":{
                    "hosts":{},
                    "kubernetes":{
                        "ssl":{
                            "certs":{}
                        }
                    }
                },
                "root":{}
             }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    二、实现思路

    1、按照每一行的路径记录 / 的位置,得到一个二维数组。
    统计一行中字符串中 / 的位置 ,得到一维数组。

        //统计一行字符串中 / 的位置
        private static List<Integer> countNum(String path){
            List<Integer> rowCount = new ArrayList<Integer>() ;
            if (!path.isEmpty()){
                char[] chars = path.toCharArray();
                for (int i = 0; i < chars.length; i++) {
                    if (chars[i] == '/'){
                        rowCount.add(i);
                    }
                }
            }
            return rowCount;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    统计多行字符串中 / 的位置 ,得到二维数组。

                //统计 有多少行 字符串 包含 多少个list(list存放 / 在字符数组中的位置)
                List<List<Integer>> colCount = new ArrayList<List<Integer>>();
                for (int i = 0; i < pathList.size(); i++) {
                    List<Integer> rowCount = countNum(pathList.get(i));
                    Map<String, Map> rowElementMap = rowElementMap(pathList.get(i));
                    mapList.add(rowElementMap);
                    colCount.add(rowCount);
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、由第1步的 / 位置 数组 进行字符串递归截串,注意 /root 这种情况即可。
    这里解释下为什么递归:

                    "/etc/hosts",
                    "/etc/kubernetes/ssl/certs",
                    "/root"
    
    • 1
    • 2
    • 3

    每一个路径都可以看成是 /文件夹名称 这种问题处理。
    截串形式为:
    /etc/kubernetes/ssl/certs
    /kubernetes/ssl/certs
    /ssl/certs
    /certs
    因此,每次需要重新获取path

                int right = rowCount.get(1);
                String pathTemp = path.substring(right);
    
    • 1
    • 2

    递归实现

        private static Map<String, Map> rowElementMap(String path){
            List<Integer> rowCount = countNum(path);
            int left = rowCount.get(0)+1;
            if (rowCount.size() == 1){
                String rowKey = path.substring(left);
                HashMap<String, Map> rowMap = new HashMap<>();
                rowMap.put(rowKey, new HashMap());
                return rowMap;
            }else {
                int right = rowCount.get(1);
                String rowKey = path.substring(left, right);
                String pathTemp = path.substring(right);
                HashMap<String, Map> rowMap = new HashMap<>();
                //注意这里的value,递归获取map
                rowMap.put(rowKey, rowElementMap(pathTemp));
                return rowMap;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    三、源码

    方法一、返回单个map的源代码

    import cn.hutool.json.JSONObject;
    import cn.hutool.json.JSONUtil;
    
    import java.util.*;
    
    /**
     * @Description:
     * @Author: AustinU
     * @CreateTime: 2022/8/18
     */
    public class Main {
        public static void main(String[] args) {
            //实现pathListToMap, 能够将输入的pathList转化为具有层级结构的map类型
            List<String> pathList = Arrays.asList(
                    "/etc/hosts",
                    "/root",
                    "/etc/kubernetes/ssl/certs"
            );
            /**
             {
                "etc":{
                    "hosts":{},
                    "kubernetes":{
                        "ssl":{
                            "certs":{}
                        }
                    }
                },
                "root":{}
             }
             */
            Map<String, Map> resultMap = pathListToMap(pathList);
            System.out.println(resultMap);
            JSONObject jsonObject = JSONUtil.parseObj(resultMap);
            System.out.println(jsonObject);
    
        }
    
        private static Map<String, Map> pathListToMap(List<String> pathList) {
            if (pathList.isEmpty()) return null;
            if (pathList.size() == 1 && countNum(pathList.get(0)).size() == 1) {
                String resKey = pathList.get(0).replaceAll("\\/", "");
                HashMap<String,Map> resMap = new HashMap<String, Map>();
                resMap.put(resKey, new HashMap<String,Map>());
                return resMap;
            }else {
                List<Map<String, Map>> mapList= new ArrayList<>();
                //统计 有多少列 字符串 包含 多少个list(list存放 / 在字符数组中的位置)
                List<List<Integer>> colCount = new ArrayList<List<Integer>>();
                for (int i = 0; i < pathList.size(); i++) {
                    List<Integer> rowCount = countNum(pathList.get(i));
                    Map<String, Map> rowElementMap = rowElementMap(pathList.get(i));
                    mapList.add(rowElementMap);
                    colCount.add(rowCount);
                }
                Map<String, Map> resMap = mapList2OneMap(mapList);
                return resMap;
            }
    
        }
    
        //将多行map合并成同一个map
        private static Map<String, Map> mapList2OneMap(List<Map<String, Map>> mapList) {
            HashMap<String,Map> resMap = new HashMap<>();
            HashMap<String,List<Map<String, Map>>> resListMap = new HashMap<>();
            List<Map<String, Map>> resMapList = new ArrayList<>();
            if (mapList.isEmpty()) return new HashMap<String, Map>();
            if (mapList.size() == 1) return mapList.get(0);
            else {
                for (int i = 0; i < mapList.size(); i++) {
                    resMap.putAll(mapList.get(i));
                }
                return resMap;
            }
        }
    
        //统计字符串中 / 的位置
        private static List<Integer> countNum(String path){
            List<Integer> rowCount = new ArrayList<Integer>() ;
            if (!path.isEmpty()){
                char[] chars = path.toCharArray();
                for (int i = 0; i < chars.length; i++) {
                    if (chars[i] == '/'){
                        rowCount.add(i);
                    }
                }
            }
            return rowCount;
        }
    
    
        private static Map<String, Map> rowElementMap(String path){
            List<Integer> rowCount = countNum(path);
            int left = rowCount.get(0)+1;
            if (rowCount.size() == 1){
                String rowKey = path.substring(left);
                HashMap<String, Map> rowMap = new HashMap<>();
                rowMap.put(rowKey, new HashMap());
                return rowMap;
            }else {
                int right = rowCount.get(1);
                String rowKey = path.substring(left, right);
                String pathTemp = path.substring(right);
                HashMap<String, Map> rowMap = new HashMap<>();
                rowMap.put(rowKey, rowElementMap(pathTemp));
                return rowMap;
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    输出结果:
    在这里插入图片描述
    运行结果放在JSON可视化工具展现如下
    在这里插入图片描述
    和期望结果对比可知,如果map中首次放入的key相同会存在覆盖value的情况。

    方法二、返回map的列表的源代码

    package ruiqi;
    
    import cn.hutool.json.JSONObject;
    import cn.hutool.json.JSONUtil;
    
    import java.util.*;
    
    /**
     * @Description:
     * @Author: AustinU
     * @CreateTime: 2022/8/18
     */
    public class MainReturnMapList {
        public static void main(String[] args) {
            //实现pathListToMap, 能够将输入的pathList转化为具有层级结构的map类型
            List<String> pathList = Arrays.asList(
                    "/etc/hosts",
                    "/etc/kubernetes/ssl/certs",
                    "/root"
            );
            /**
             {
                "etc":{
                    "hosts":{},
                    "kubernetes":{
                        "ssl":{
                            "certs":{}
                        }
                    }
                },
                "root":{}
             }
             */
            Map<String, List<Map<String, Map>>> resultMap = pathListToMap(pathList);
            System.out.println(resultMap);
            JSONObject jsonObject = JSONUtil.parseObj(resultMap);
            System.out.println(jsonObject);
    
        }
    
        private static Map<String, List<Map<String, Map>>> pathListToMap(List<String> pathList) {
            if (pathList.isEmpty()) return null;
            if (pathList.size() == 1 && countNum(pathList.get(0)).size() == 1) {
                String resKey = pathList.get(0).replaceAll("\\/", "");
                HashMap<String,Map> resMap = new HashMap<String, Map>();
                resMap.put(resKey, new HashMap<String,Map>());
                List<Map<String, Map>> mapList = new ArrayList<>();
                mapList.add(resMap);
                Map<String, List<Map<String, Map>>> resMapList = new HashMap<>();
                resMapList.put(resKey, mapList);
                return resMapList;
            }else {
                List<Map<String, Map>> mapList= new ArrayList<>();
                int n = pathList.size();
                //统计 有多少列 字符串 包含 多少个list(list存放 / 在字符数组中的位置)
                List<List<Integer>> colCount = new ArrayList<List<Integer>>();
                for (int i = 0; i < pathList.size(); i++) {
                    List<Integer> rowCount = countNum(pathList.get(i));
                    Map<String, Map> rowElementMap = rowElementMap(pathList.get(i));
                    mapList.add(rowElementMap);
                    colCount.add(rowCount);
                }
                Map<String, List<Map<String, Map>>> resMap = mapList2OneMap(mapList);
                return resMap;
            }
    
        }
    
        //将多行map合并成同一个map
        private static Map<String, List<Map<String, Map>>> mapList2OneMap(List<Map<String, Map>> mapList) {
            HashMap<String,Map> resMap = new HashMap<>();
            HashMap<String,List<Map<String, Map>>> resListMap = new HashMap<>();
            List<Map<String, Map>> resMapList = new ArrayList<>();
            if (mapList.isEmpty()) return new HashMap<String, List<Map<String, Map>>>();
            else {
                for (int i = 0; i < mapList.size(); i++) {
                    for (Map.Entry<String, Map> mapEntry : mapList.get(i).entrySet()) {
    
                        if (!resMap.containsKey(mapEntry.getKey())){
                            resMapList.add(mapEntry.getValue());
                            resListMap.put(mapEntry.getKey(), resMapList);
                        }else {
                            //具有相同key
                            resMapList.add(mapEntry.getValue());
                        }
                    }
                }
                return resListMap;
            }
        }
        
        //统计字符串中 有几个 /
        private static List<Integer> countNum(String path){
            List<Integer> rowCount = new ArrayList<Integer>() ;
            if (!path.isEmpty()){
                char[] chars = path.toCharArray();
                for (int i = 0; i < chars.length; i++) {
                    if (chars[i] == '/'){
                        rowCount.add(i);
                    }
                }
            }
            return rowCount;
        }
    
        private static Map<String, Map> rowElementMap(String path){
            List<Integer> rowCount = countNum(path);
            int left = rowCount.get(0)+1;
            if (rowCount.size() == 1){
                String rowKey = path.substring(left);
                HashMap<String, Map> rowMap = new HashMap<>();
                rowMap.put(rowKey, new HashMap());
                return rowMap;
            }else {
                int right = rowCount.get(1);
                String rowKey = path.substring(left, right);
                String pathList = path.substring(right);
                HashMap<String, Map> rowMap = new HashMap<>();
                rowMap.put(rowKey, rowElementMap(pathList));
                return rowMap;
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125

    输出结果:
    在这里插入图片描述
    运行结果放在JSON可视化工具展现如下
    在这里插入图片描述
    这里存在的问题是节点信息存在无中生有。
    如果大家对 这道题有见解欢迎留言。

  • 相关阅读:
    七:ffmpeg命令提取音频视频
    Windows安装SSH教程
    Spring Cache 带你飞(一)
    5.2.鸿蒙LiteOS-M los_dispatch
    通讯录-C/C++
    每日一练 | 网络工程师软考真题Day41
    opencv dots_image_kernel
    【牛客网刷题系列 之 Verilog快速入门】~ 使用函数实现数据大小端转换
    docker 生成镜像的几个问题
    C++校园导游程序及通信线路设计
  • 原文地址:https://blog.csdn.net/Austin_/article/details/126454901