这可能是一个简单的Java流问题。说,我有一个List<Student>
对象。
public class Student {
public String name;
public Set<String> subjects;
public Set<String> getSubjects() {
return subjects;
}
}
如何获取学生名单上的所有科目?
我可以为每个循环使用a。如何转换以下代码以使用流?
for (Student student : students) {
subjectsTaken.addAll(student.getSubjects());
}
这是我尝试使用Java 8流的尝试。这给我一个Incompatible types
错误。
Set<String> subjectsTaken = students.stream()
.map(student -> student.getSubjects())
.collect(Collectors.toSet());
答案 0 :(得分:5)
您当前的代码产生一个Set<Set<String>>
,而不是Set<String>
。
您应该使用flatMap
,而不是map
:
Set<String> subjectsTaken =
students.stream() // Stream<Student>
.flatMap(student -> student.getSubjects().stream()) // Stream<String>
.collect(Collectors.toSet()); // Set<String>
答案 1 :(得分:4)
尝试一下:
Set<String> subjectsTaken =
students.stream()
.map(Student::getSubjects)
.flatMap(Set::stream)
.collect(Collectors.toSet());
想法是首先将学生映射到他们的主题,然后将Stream<Set<String>>
展平到Stream<String>
,最后将流收集到Set
。
我建议您在可能的情况下(如果不降低可读性)使用方法引用而不是 lambda表达式。
答案 2 :(得分:1)
使用Stream<T>#<R>collect
的另一种选择:
students.stream()
.map(Student::getSubjects)
.<Set<String>>collect(HashSet::new, Collection::addAll, Collection::addAll)