Представление дерева значений в виде плоской карты
Есть карта значений Map<String, Object>, элементами которой могут быть либо такие же карты, либо списки значений List<Object>, либо просто String. Элементами списков также могут быть Map, List или String. Глубина вложенности дерева не известна. Нужно представить эту структуру в виде плоской карты (flatMap) типа Map<String, String> с учетом вложенности. Например:
public static void main(String[] args) {
TreeMap<String, Object> treeMap = new TreeMap<String, Object>() {{
put("1999", new TreeMap<String, Object>() {{
put("3", Arrays.asList("23", "24", "25"));
put("4", Arrays.asList("1", "2", new TreeMap<String, Object>() {{
put("10", "42");
}}));
}});
put("2001", new TreeMap<String, Object>() {{
put("11", new TreeMap<String, Object>() {{
put("7", Arrays.asList("23", "24", "25"));
put("9", Arrays.asList("1", "2", "3"));
}});
put("12", "45");
}});
}};
System.out.println(treeMap);
}
Карта значений:
{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}
См. Восстановление дерева значений по его плоской карте
Ответы (1 шт):
Можно рекурсивно обойти эту карту и обработать значения ее элементов в зависимости от их типа: Map, List, или String.
public static void main(String[] args) {
TreeMap<String, Object> treeMap = new TreeMap<String, Object>() {{
put("1999", new TreeMap<String, Object>() {{
put("3", Arrays.asList("23", "24", "25"));
put("4", Arrays.asList("1", "2", new TreeMap<String, Object>() {{
put("10", "42");
}}));
}});
put("2001", new TreeMap<String, Object>() {{
put("11", new TreeMap<String, Object>() {{
put("7", Arrays.asList("23", "24", "25"));
put("9", Arrays.asList("1", "2", "3"));
}});
put("12", "45");
}});
}};
TreeMap<String, String> flatMap = new TreeMap<>();
processMap("", treeMap, flatMap);
System.out.println(treeMap);
System.out.println(flatMap);
}
private static void processMap(String prefix,
Map<String, Object> map,
Map<String, String> flatMap) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
processEntry(prefix, key, value, flatMap);
}
}
private static void processList(String prefix,
List<Object> list,
Map<String, String> 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<String, String> flatMap) {
if (value instanceof Map) {
processMap(prefix + key + ".", (Map<String, Object>) value, flatMap);
} else if (value instanceof List) {
processList(prefix + key + ":", (List<Object>) value, flatMap);
} else if (value instanceof String) {
flatMap.put(prefix + key, (String) value);
}
}
Исходная карта:
{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}
См. Flatten nested Map containing with unknown level of nested Arrays and Maps recursively