Take a JSON that has been converted to Map<String, Object>
:
{
"key1": "value1",
"key2": {
"nestedKey1": "nested value",
"nestedKey2": {
"nestedKey1": "nested value"
}
}
}
Where Object
value could be some primitive type or a nested Map<String, Object>
.
My goal is to get a flat map:
{
"key1": "value1",
"key2.nestedKey1": "nested value",
"key2.nestedKey2.nestedKey1": "nested value"
}
How? Any library that already does it?
Yes, you can do it in Java8 too.
Main test method:
Map<String, Object> in = new HashMap<>();
in.put("key1", "val1");
Map<String, Object> lvl1 = new HashMap<>();
lvl1.put("key2", "val2");
lvl1.put("key3", Collections.singletonMap("k3", "v3"));
in.put("key2", lvl1);
Map<String, Object> out = flatten(in);
Transformer methods:
private Map<String, Object> flatten(Map<String, Object> in) {
return in.entrySet().stream()
.flatMap(entry -> flatten(entry).entrySet().stream())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue));
}
private Map<String, Object> flatten(Map.Entry<String, Object> in) {
// for other then Map objects return them
if (!Map.class.isInstance(in.getValue())) {
return Collections.singletonMap(in.getKey(), in.getValue());
}
// extract the key prefix for nested objects
String prefix = in.getKey();
Map<String, Object> values = (Map<String, Object>) in.getValue();
// create a new Map, with prefix added to each key
Map<String, Object> flattenMap = new HashMap<>();
values.keySet().forEach(key -> {
// use a dot as a joining char
flattenMap.put(prefix + "." + key, values.get(key));
});
// use recursion to flatten the structure deeper
return flatten(flattenMap);
}
There is a library called Json Flattener
. I guess it will solve your problem. Include the library into your project using maven:
<dependency>
<groupId>com.github.wnameless</groupId>
<artifactId>json-flattener</artifactId>
<version>0.6.0</version>
</dependency>
In your case:
String json = "{ \"key1\": \"value1\", \"key2\": { \"nestedKey1\": \"nested value\", \"nestedKey2\": { \"nestedKey1\": \"nested value\" } } }";
Map<String, Object> flattenJson = JsonFlattener.flattenAsMap(json);
System.out.println(flattenJson);
Output:
{"key1":"value1","key2.nestedKey1":"nested value","key2.nestedKey2.nestedKey1":"nested value"}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With