温馨提示:本文翻译自stackoverflow.com,查看原文请点击:java - Flatten nested Map containing with unknown level of nested Arrays and Maps recursively
arrays flatten hashmap java list

java - 展平嵌套的Map,其中包含未知级别的嵌套数组,并且递归地映射

发布于 2021-04-18 12:03:51

我有一个嵌套HashMapString包含任何键ListMapString值。我想像下面这样压扁它们。

数据如下:

import java.util.*;
import java.util.stream.*;
public class MyClass {
    public static void main(String args[]) {
        Map<String, Object> dates = new HashMap<String, Object>() {{
            put("1999", new HashMap<String, Object>() {{
                put("3", Arrays.asList("23", "24", "25"));
                put("4", Arrays.asList("1", "2", "3"));
            }});
            put("2001", new HashMap<String, Object>() {{
                put("11", new HashMap<String, Object>() {{
                    put("7", Arrays.asList("23", "24", "25"));
                    put("9", Arrays.asList("1", "2", "3"));
                }});
                put("12", "45");
            }});
        }};
        System.out.println(dates);
    }
}

map看起来像:

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

map的展平应如下所示:

{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, 1999.3.1=23, 1999.3.2=24, 1999.3.3=25,
 1999.4.1=1, 1999.4.2=2, 1999.4.3=3}

注意:嵌套数组或映射的级别未知,可能会超过2个级别。

查看更多

提问者
Sandeep Kadapa
被浏览
0
iota 2020-07-05 01:29

你可以使用递归来展平Map每次遇到a时Map,通过展平来递归Map; 当你遇到时List,请对其进行迭代,然后将索引添加到当前键中。否则,可以简单地设置一个值。请参阅此处的以下代码

public static Map<String, Object> flatten(final Map<String, Object> map) {
    return flatten("", map, new HashMap<>());
    //use new TreeMap<>() to order map based on key
}

@SuppressWarnings("unchecked")//recursive helper method
private static Map<String, Object> flatten(final String key, final Map<String, Object> map,
        final Map<String, Object> result) {
    final Set<Map.Entry<String, Object>> entries = map.entrySet();
    if (!entries.isEmpty()) {
        for (final Map.Entry<String, Object> entry : entries) {
            //iterate over entries
            final String currKey = key + (key.isEmpty() ? "" : '.') + entry.getKey();
           //append current key to previous key, adding a dot if the previous key was not an empty String
            final Object value = entry.getValue();
            if (value instanceof Map) {//current value is a Map
                flatten(currKey, (Map<String, Object>) value, result);//flatten Map
            } else if (value instanceof List) {//current value is a List
                final List<Object> list = (List<Object>) value;
                for (int i = 0, size = list.size(); i < size; i++) {
                    result.put(currKey + '.' + (i + 1), list.get(i));
                }
                //iterate over the List and append the index to the current key when setting value
            } else {
                result.put(currKey, value);//set normal value
            }
        }
    }
    return result;
}
public static void main(final String[] args){
    final Map<String, Object> flattened = flatten(dates);
    System.out.println(flattened);
}