I have a String input in the following format:
Input String: [{ "id":"1", "name":"A", "address":"St 1"},{ "id":"2", "name":"B", "address":"St 2"}, ...]
And I want to be able to convert this to a Map<String, Map<String, String>>
format.
So, something like:
Required Output Format: {1: {id:1, name:"A", address: "St 1"} 2: {id:2, name:"B", address: "St 2"}}
I created a class to help in parsing the input:
public class Student{
private String id;
private String name;
private String address;
}
Which I am trying to do through Jackson's ObjectMapper
to get the data in the format: List<Student>
format and then use Collectors.toMap()
to convert it to a Map of Maps format.
All the examples I have seen so far suggest an approach like:
List<Student> student = objectMapper.readValue(inputString, new TypeReference<List<Student>>(){});
Map<String, Student> studentTempMap = student.stream()
.collect(Collectors.toMap(
Student::getId,
Function.identity()
));
Which makes the studentTempMap
something like:
{ 1: object of Student("id":"1", "name":"A", "address":"St 1"),
2: object of Student("id":"2", "name":"B", "address":"St 2"),
... }
A brute force approach from here:
- create a new Map studentMap
- Iterate over keys (which are "id") in studentTempMap.
- Then create another Map, temp.
- Add keys "id", "name", and "address" and values using something like
studentTempMap.get(2).get("id")
, and something similar for all the other keys (name and address). Where 2 would be the current iterator key over the MapstudentTempMap
. - Finally add a key say as 2 (current iterator) and value temp in the
studentMap
.
I do not want to use this brute force approach as I have a large number of Student
objects.
Is there a way through ObjectMapper
to get the output directly in the form of Map<String, Map<String, String>>
format?
Or is there a way through Collectors.toMap
to parse it to the above format?
CodePudding user response:
I want to be able to convert this to a
Map<String, Map<String, String>>
If you want to obtain a nested map of strings Map<String,Map<String,String>>
as a result, you don't need to convert JSON into a list of POJO.
Instead, you can parse JSON into a list of maps List<Map<String,String>>
and then generate a nested map.
String inputString = """
[{ "id":"1", "name":"A", "address":"St 1"},
{ "id":"2", "name":"B", "address":"St 2"}]""";
ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, String>> students = objectMapper.readValue(
inputString, new TypeReference<>() {}
);
Map<String, Map<String, String>> studentMapById = students.stream()
.collect(Collectors.toMap(
map -> map.get("id"), // key
Function.identity(), // value
(left, right) -> left // resolving duplicates
));
studentMapById.forEach((k, v) -> System.out.println(k " : " v));
Output:
1 : {id=1, name=A, address=St 1}
2 : {id=2, name=B, address=St 2}