Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructing list from multi level map in Java 8

I have a multi-level map as follows:

 Map<String, Map<String, Student> outerMap = 
    {"cls1" : {"xyz" : Student(rollNumber=1, name="test1")}, 
     "cls2" : {"abc" : Student(rollNumber=2, name="test2")}}

Now I want to construct a list of string from the above map as follows:

["In class cls1 xyz with roll number 1",
 "In class cls2 abc with roll number 2"] 

I have written as follows, but this is not working, in this context I have gone through the post as well: Java 8 Streams - Nested Maps to List, but did not get much idea.

 List<String> classes = outerMap.keySet();
 List<String> studentList = classes.stream()
      .map(cls -> 
           outerMap.get(cls).keySet().stream()
           .map(student -> "In class "+ cls +
            student + " with roll number " +
            outerMap.get(cls).get(student).getRollNum() +"\n"
            ).collect(Collectors.toList());
like image 653
Joy Avatar asked Jan 17 '19 04:01

Joy


People also ask

How will you convert a list into map using streams in Java 8?

Using Java 8 you can do following : Map<Key, Value> result= results . stream() . collect(Collectors.


2 Answers

You may do it like so,

List<String> formattedOutput = outerMap
    .entrySet().stream()
    .flatMap(e -> e.getValue().entrySet().stream().map(se -> "In class " + e.getKey()
        + " " + se.getKey() + " with roll number " + se.getValue().getRollNumber()))
    .collect(Collectors.toList());

You have to use the flatMap operator instead of map operator.

like image 68
Ravindra Ranwala Avatar answered Oct 24 '22 22:10

Ravindra Ranwala


You can simply use Map.forEach for this operation as:

List<String> messages = new ArrayList<>();
outerMap.forEach((cls, students) ->
        students.forEach((name, student) -> 
                messages.add(convertToMessage(cls, name, student.getRollNumber()))));

where convertToMessage is a util as :

// this could be made cleaner using 'format'
String convertToMessage(String cls, String studentName, String rollNumber) {
    return "In class" + cls + "--> " + studentName + " with roll number: " + rollNumber;
}
like image 40
Naman Avatar answered Oct 24 '22 22:10

Naman