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?
Advertisement
Answer
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}