Flatten nested Map containing with unknown level of nested Arrays and Maps recursively

后端 未结 2 1211
野的像风
野的像风 2021-01-19 15:06

I have a nested HashMap with String keys that contains either List, Map, or String values. I would like to f

2条回答
  •  灰色年华
    2021-01-19 15:54

    You can iterate over this map, and process each entry value, depending on its instance of: Map, List, or String. Since the level of nested arrays or maps is unknown, I have modified a little your code example and flat map format for clarity, also I used TreeMap instead of HashMap for entries ordering.

    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap() {{
            put("1999", new TreeMap() {{
                put("3", Arrays.asList("23", "24", "25"));
                put("4", Arrays.asList("1", "2", new TreeMap() {{
                    put("10", "42");
                }}));
            }});
            put("2001", new TreeMap() {{
                put("11", new TreeMap() {{
                    put("7", Arrays.asList("23", "24", "25"));
                    put("9", Arrays.asList("1", "2", "3"));
                }});
                put("12", "45");
            }});
        }};
    
        TreeMap flatMap = new TreeMap<>();
        processMap("", treeMap, flatMap);
    
        System.out.println(treeMap);
        System.out.println(flatMap);
    }
    
    private static void processMap(String prefix,
                                   Map map,
                                   Map flatMap) {
        for (Map.Entry entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            processEntry(prefix, key, value, flatMap);
        }
    }
    
    private static void processList(String prefix,
                                    List list,
                                    Map flatMap) {
        for (int i = 0; i < list.size(); i++) {
            String key = String.valueOf(i + 1);
            Object value = list.get(i);
            processEntry(prefix, key, value, flatMap);
        }
    }
    
    
    @SuppressWarnings("unchecked")
    private static void processEntry(String prefix,
                                     String key,
                                     Object value,
                                     Map flatMap) {
        if (value instanceof Map) {
            processMap(prefix + key + ".", (Map) value, flatMap);
        } else if (value instanceof List) {
            processList(prefix + key + ":", (List) value, flatMap);
        } else if (value instanceof String) {
            flatMap.put(prefix + key, (String) value);
        }
    }
    
    

    Sample map:

    {1999={3=[23, 24, 25], 4=[1, 2, {10=42}]},
     2001={11={7=[23, 24, 25], 9=[1, 2, 3]}, 12=45}}
    

    Flattened map:

    {1999.3:1=23, 1999.3:2=24, 1999.3:3=25, 1999.4:1=1, 1999.4:2=2, 1999.4:3.10=42,
     2001.11.7:1=23, 2001.11.7:2=24, 2001.11.7:3=25,
     2001.11.9:1=1, 2001.11.9:2=2, 2001.11.9:3=3, 2001.12=45}
    

    Opposite: Restoring a value tree from its flat map representation.

    提交回复
    热议问题