从平面地图表示中恢复价值树
Restoring a value tree from its flat map representation
我有一个 Map<String, String>
类型的平面图,我想从中恢复原始值树 Map<String, Object>
。树的元素可以是 Map<String, Object>
,或 List<Object>
,或只是 String
。树的深度没有限制。例如:
public static void main(String[] args) {
TreeMap<String, String> flatMap = new TreeMap<String, String>() {{
put("1999.3:1", "23");
put("1999.3:2", "24");
put("1999.3:3", "25");
put("1999.4:1", "1");
put("1999.4:2", "2");
put("1999.4:3.10", "42");
put("2001.11.7:1", "23");
put("2001.11.7:2", "24");
put("2001.11.7:3", "25");
put("2001.11.9:1", "1");
put("2001.11.9:2", "2");
put("2001.11.9:3", "3");
put("2001.12", "45");
}};
System.out.println(flatMap);
}
平面图:
{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}
原始值树:
{1999={3=[23, 24, 25], 4=[1, 2, {10=42}]},
2001={11={7=[23, 24, 25], 9=[1, 2, 3]}, 12=45}}
对面:.
迭代平面地图键并恢复原始树。对于从左到右的每个键,查找分隔符:
- 点
.
- 嵌套对象是地图。下一个数字是地图中的关键。
- 冒号
:
- 嵌套对象是一个列表。下一个数字是列表中的索引(从 1
开始)。
然后递归处理嵌套对象,通过平面图的key向右移动:
public static void main(String[] args) {
TreeMap<String, String> flatMap = new TreeMap<String, String>() {{
put("1999.3:1", "23");
put("1999.3:2", "24");
put("1999.3:3", "25");
put("1999.4:1", "1");
put("1999.4:2", "2");
put("1999.4:3.10", "42");
put("2001.11.7:1", "23");
put("2001.11.7:2", "24");
put("2001.11.7:3", "25");
put("2001.11.9:1", "1");
put("2001.11.9:2", "2");
put("2001.11.9:3", "3");
put("2001.12", "45");
}};
TreeMap<String, Object> originalMap = new TreeMap<>();
flatMap.forEach((key, value) -> processMap(key, value, originalMap));
System.out.println(flatMap);
System.out.println(originalMap);
}
@SuppressWarnings("unchecked")
private static void processMap(String flatMapKey,
String flatMapValue,
Map<String, Object> map) {
int dot = flatMapKey.indexOf('.');
int colon = flatMapKey.indexOf(':');
// nested map
if (dot > -1 && (dot < colon || colon == -1)) {
String key = flatMapKey.substring(0, dot);
Object nestedMap = map.get(key);
if (nestedMap == null) {
map.put(key, new TreeMap<>());
}
nestedMap = map.get(key);
processMap(flatMapKey.substring(dot + 1),
flatMapValue, (Map<String, Object>) nestedMap);
}
// nested list
else if (colon > -1 && (colon < dot || dot == -1)) {
String key = flatMapKey.substring(0, colon);
Object nestedList = map.get(key);
if (nestedList == null) {
map.put(key, new ArrayList<>());
}
nestedList = map.get(key);
processList(flatMapKey.substring(colon + 1),
flatMapValue, (List<Object>) nestedList);
}
// insert value
else if (dot == colon) {
map.put(flatMapKey, flatMapValue);
}
}
@SuppressWarnings("unchecked")
private static void processList(String flatMapKey,
String flatMapValue,
List<Object> list) {
int dot = flatMapKey.indexOf('.');
int colon = flatMapKey.indexOf(':');
// nested map
if (dot > -1 && (dot < colon || colon == -1)) {
int index = Integer.parseInt(flatMapKey.substring(0, dot));
while (list.size() < index) {
list.add(null);
}
Object nestedMap = list.get(index - 1);
if (nestedMap == null) {
list.set(index - 1, new TreeMap<>());
}
nestedMap = list.get(index - 1);
processMap(flatMapKey.substring(dot + 1),
flatMapValue, (Map<String, Object>) nestedMap);
}
// nested list
else if (colon > -1 && (colon < dot || dot == -1)) {
int index = Integer.parseInt(flatMapKey.substring(0, colon));
while (list.size() < index) {
list.add(null);
}
Object nestedList = list.get(index - 1);
if (nestedList == null) {
list.set(index - 1, new ArrayList<>());
}
nestedList = list.get(index - 1);
processList(flatMapKey.substring(colon + 1),
flatMapValue, (List<Object>) nestedList);
}
// insert value
else if (dot == colon) {
int index = Integer.parseInt(flatMapKey);
while (list.size() < index) {
list.add(null);
}
list.set(index - 1, flatMapValue);
}
}
平面图:
{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}
原始树:
{1999={3=[23, 24, 25], 4=[1, 2, {10=42}]},
2001={11={7=[23, 24, 25], 9=[1, 2, 3]}, 12=45}}
我有一个 Map<String, String>
类型的平面图,我想从中恢复原始值树 Map<String, Object>
。树的元素可以是 Map<String, Object>
,或 List<Object>
,或只是 String
。树的深度没有限制。例如:
public static void main(String[] args) {
TreeMap<String, String> flatMap = new TreeMap<String, String>() {{
put("1999.3:1", "23");
put("1999.3:2", "24");
put("1999.3:3", "25");
put("1999.4:1", "1");
put("1999.4:2", "2");
put("1999.4:3.10", "42");
put("2001.11.7:1", "23");
put("2001.11.7:2", "24");
put("2001.11.7:3", "25");
put("2001.11.9:1", "1");
put("2001.11.9:2", "2");
put("2001.11.9:3", "3");
put("2001.12", "45");
}};
System.out.println(flatMap);
}
平面图:
{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}
原始值树:
{1999={3=[23, 24, 25], 4=[1, 2, {10=42}]},
2001={11={7=[23, 24, 25], 9=[1, 2, 3]}, 12=45}}
对面:
迭代平面地图键并恢复原始树。对于从左到右的每个键,查找分隔符:
- 点
.
- 嵌套对象是地图。下一个数字是地图中的关键。 - 冒号
:
- 嵌套对象是一个列表。下一个数字是列表中的索引(从1
开始)。
然后递归处理嵌套对象,通过平面图的key向右移动:
public static void main(String[] args) {
TreeMap<String, String> flatMap = new TreeMap<String, String>() {{
put("1999.3:1", "23");
put("1999.3:2", "24");
put("1999.3:3", "25");
put("1999.4:1", "1");
put("1999.4:2", "2");
put("1999.4:3.10", "42");
put("2001.11.7:1", "23");
put("2001.11.7:2", "24");
put("2001.11.7:3", "25");
put("2001.11.9:1", "1");
put("2001.11.9:2", "2");
put("2001.11.9:3", "3");
put("2001.12", "45");
}};
TreeMap<String, Object> originalMap = new TreeMap<>();
flatMap.forEach((key, value) -> processMap(key, value, originalMap));
System.out.println(flatMap);
System.out.println(originalMap);
}
@SuppressWarnings("unchecked")
private static void processMap(String flatMapKey,
String flatMapValue,
Map<String, Object> map) {
int dot = flatMapKey.indexOf('.');
int colon = flatMapKey.indexOf(':');
// nested map
if (dot > -1 && (dot < colon || colon == -1)) {
String key = flatMapKey.substring(0, dot);
Object nestedMap = map.get(key);
if (nestedMap == null) {
map.put(key, new TreeMap<>());
}
nestedMap = map.get(key);
processMap(flatMapKey.substring(dot + 1),
flatMapValue, (Map<String, Object>) nestedMap);
}
// nested list
else if (colon > -1 && (colon < dot || dot == -1)) {
String key = flatMapKey.substring(0, colon);
Object nestedList = map.get(key);
if (nestedList == null) {
map.put(key, new ArrayList<>());
}
nestedList = map.get(key);
processList(flatMapKey.substring(colon + 1),
flatMapValue, (List<Object>) nestedList);
}
// insert value
else if (dot == colon) {
map.put(flatMapKey, flatMapValue);
}
}
@SuppressWarnings("unchecked")
private static void processList(String flatMapKey,
String flatMapValue,
List<Object> list) {
int dot = flatMapKey.indexOf('.');
int colon = flatMapKey.indexOf(':');
// nested map
if (dot > -1 && (dot < colon || colon == -1)) {
int index = Integer.parseInt(flatMapKey.substring(0, dot));
while (list.size() < index) {
list.add(null);
}
Object nestedMap = list.get(index - 1);
if (nestedMap == null) {
list.set(index - 1, new TreeMap<>());
}
nestedMap = list.get(index - 1);
processMap(flatMapKey.substring(dot + 1),
flatMapValue, (Map<String, Object>) nestedMap);
}
// nested list
else if (colon > -1 && (colon < dot || dot == -1)) {
int index = Integer.parseInt(flatMapKey.substring(0, colon));
while (list.size() < index) {
list.add(null);
}
Object nestedList = list.get(index - 1);
if (nestedList == null) {
list.set(index - 1, new ArrayList<>());
}
nestedList = list.get(index - 1);
processList(flatMapKey.substring(colon + 1),
flatMapValue, (List<Object>) nestedList);
}
// insert value
else if (dot == colon) {
int index = Integer.parseInt(flatMapKey);
while (list.size() < index) {
list.add(null);
}
list.set(index - 1, flatMapValue);
}
}
平面图:
{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}
原始树:
{1999={3=[23, 24, 25], 4=[1, 2, {10=42}]},
2001={11={7=[23, 24, 25], 9=[1, 2, 3]}, 12=45}}