Java 以递归方式展平包含未知嵌套数组和映射级别的嵌套映射

Java 以递归方式展平包含未知嵌套数组和映射级别的嵌套映射,java,arrays,list,hashmap,flatten,Java,Arrays,List,Hashmap,Flatten,我有一个嵌套的HashMap,其中包含List、Map或String值的String键。我想像下面一样把它们压扁 以下是数据: import java.util.*; import java.util.stream.*; public class MyClass { public static void main(String args[]) { Map<String, Object> dates = new HashMap<String, Object

我有一个嵌套的
HashMap
,其中包含
List
Map
String
值的
String
键。我想像下面一样把它们压扁

以下是数据:

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);
    }
}
地图的展平应如下所示:

{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个级别。

您可以使用递归展平
映射。每次遇到
映射
,通过展平该
映射
进行递归;当您遇到一个
列表
时,迭代该列表并将索引添加到当前键。一个值可以简单地设置为其他值。请参阅下面的代码

公共静态地图展平(最终地图){
返回展平(“,map,newhashmap());
//使用new TreeMap()根据键对映射进行排序
}
@SuppressWarnings(“未选中”)//递归帮助程序方法
私有静态地图展平(最终字符串键、最终地图、,
最终地图结果){
最终设置条目=map.entrySet();
如果(!entries.isEmpty()){
用于(最终地图。条目:条目){
//迭代条目
最后一个字符串currKey=key+(key.isEmpty()?“”:‘.)+entry.getKey();
//将当前键附加到上一个键,如果上一个键不是空字符串,则添加一个点
最终对象值=entry.getValue();
如果(value instanceof Map){//当前值是一个映射
展平(currKey,(Map)值,结果);//展平Map
}else如果(value instanceof List){//当前值是一个列表
最终列表=(列表)值;
for(int i=0,size=list.size();i
您可以迭代此映射,并根据其实例处理每个条目值:
映射
列表
字符串
。由于嵌套数组或映射的级别未知,为了清晰起见,我对您的代码示例和平面映射格式进行了一些修改,还使用了
TreeMap
而不是
HashMap
对条目进行排序

publicstaticvoidmain(字符串[]args){
TreeMap TreeMap=newtreemap(){{
付诸表决(“1999年”,新树状图(){{
put(“3”,Arrays.asList(“23”,“24”,“25”);
put(“4”,Arrays.asList(“1”,“2”,newtreemap()){{
付诸表决(“10”、“42”);
}}));
}});
put(“2001”,新树形图(){{
放置(“11”,新树形图(){{
put(“7”,Arrays.asList(“23”、“24”、“25”);
put(“9”,Arrays.asList(“1”、“2”、“3”);
}});
付诸表决(“12”、“45”);
}});
}};
TreeMap flatMap=新的TreeMap();
processMap(“”,treeMap,flatMap);
System.out.println(树映射);
System.out.println(平面图);
}
private static void processMap(字符串前缀,
地图,
地图(平面图){
对于(Map.Entry:Map.entrySet()){
String key=entry.getKey();
对象值=entry.getValue();
processEntry(前缀、键、值、平面图);
}
}
private static void processList(字符串前缀,
名单,
地图(平面图){
对于(int i=0;i
@SuppressWarnings(“未选中”)
私有静态void processEntry(字符串前缀,
字符串键,
对象值,
地图(平面图){
if(映射的值实例){
processMap(前缀+键+“,(Map)值,flatMap);
}else if(列表的值实例){
processList(前缀+键+“:”,(列表)值,flatMap);
}else if(字符串的值实例){
flatMap.put(前缀+键,(字符串)值);
}
}

示例地图:

{1999={3=[23, 24, 25], 4=[1, 2, {10=42}]},
 2001={11={7=[23, 24, 25], 9=[1, 2, 3]}, 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.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}


相反:。

如果级别数量未知,则应考虑实现递归方法。要做到这一点,请考虑递归的循环部分和结束条件。@genius42是的,我需要一些检查,直到没有映射或数组,并且所有内容都被展平。问题是我对java还不熟悉,无法理解如何实现它,这就是为什么我在这里发布这个问题。我真的很感激有解释的解决方案。我现在没有时间给你提供解决方案。我可以晚些时候或者明天做。但给你一个想法:看看你有不同的案例(地图或列表),然后处理它们。地图应该在列表不应该的地方递归处理。如果你能添加一些解释或注释,那就太完美了。谢谢你。@SandeepKadapa没问题。
{1999={3=[23, 24, 25], 4=[1, 2, {10=42}]},
 2001={11={7=[23, 24, 25], 9=[1, 2, 3]}, 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.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}