This might be a simple Java streams question. Say, I have a List<Student>
object.
public class Student {
public String name;
public Set<String> subjects;
public Set<String> getSubjects() {
return subjects;
}
}
How can I get all the subjects taken by the list of students?
I can do this using a for each loop. How can I convert the below code to use Streams?
for (Student student : students) {
subjectsTaken.addAll(student.getSubjects());
}
Here is my attempt at using Java 8 streams. This gives me an Incompatible types
error.
Set<String> subjectsTaken = students.stream()
.map(student -> student.getSubjects())
.collect(Collectors.toSet());
Your current code produces a Set<Set<String>>
, not a Set<String>
.
You should use flatMap
, not map
:
Set<String> subjectsTaken =
students.stream() // Stream<Student>
.flatMap(student -> student.getSubjects().stream()) // Stream<String>
.collect(Collectors.toSet()); // Set<String>
Try this:
Set<String> subjectsTaken =
students.stream()
.map(Student::getSubjects)
.flatMap(Set::stream)
.collect(Collectors.toSet());
The idea is to map the students to their subjects first, then flatten the Stream<Set<String>>
to Stream<String>
and finally collect the stream to a Set
.
I would suggest you to use method references instead of lambda expressions where it's possible (if it doesn't degrade readability).
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