Reputation: 997
@Getter
static class Student {
private Map<Status, Marks> statusAndMarks;
}
class Status {
}
class Marks {
}
Map<Status, Student> map = new HashMap<>();
for (Student student : studentList) {
for (Status status : student.getStatusAndMarks().keySet()) {
map.put(status, student);
}
}
How do I write the above written code in functional style in Java 8? I have written the following code but how do I write that the result of my code is an immutable map and I do not need to create a map before the lambda?
studentList
.forEach(student -> {
student
.getStatusAndMarks()
.keySet().stream()
.map(key -> map.put(key, statusKeyImportantMessage));
});
Upvotes: 3
Views: 124
Reputation: 31878
You were close enough if you would have used forEach
for iterating the keyset again as:
Map<Status, Student> map = new HashMap<>();
studentList.forEach(student ->
student.getStatusAndMarks().keySet()
.forEach(k -> map.put(k,student)));
A similar representation as stated in another answer for this would be
Map<Status, Student> map = studentList.stream()
.flatMap(s -> s.getStatusAndMarks().keySet()
.stream()
.map(status -> new AbstractMap.SimpleEntry<>(status, s)))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b));
Note, the merge function is to overwrite a new student with the same status found later in the iteration. On the other hand, what could be really handy information to query would be a list of students given a status. These can be grouped using a similar stream pipeline as following:
Map<Status, List<Student>> statusWiseStudent = studentList.stream()
.flatMap(s -> s.getStatusAndMarks().keySet()
.stream()
.map(status -> new AbstractMap.SimpleEntry<>(status, s)))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
Upvotes: 1
Reputation: 4120
You can try something like this:
studentList.stream()
.flatMap(student -> student.getStatusAndMarks()
.keySet().stream().map(status -> Map.entry(status, student)))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map.entry
is from Java 9. For lower Java it can be replaced with:
status -> new AbstractMap.SimpleEntry(status, student)
Upvotes: 1