Java 8流收集集

时间:2017-10-04 06:38:09

标签: java-8 java-stream

我有两张地图,即

Map<String, Set<String>> courseTeacherMap = {course1: [teacher1, teacher2], ...}
Map<String, Set<String>> teacherStudentMap = {teacher1: [student1, student2], ...}

我定义了一个具有非常简单结构的类courseStudentPair

public class courseStudentPair{
    String studentName; // Taken from teacherStudentMap
    String courseName; // Taken from courseTeacherMap
}

我的目标是从两张地图中获取Set<courseStudentPair>。只要教师A正在教授课程C,teacherStudentMap中关键A的价值集中的每个学生都被认为是学习C的学生。

例如,给定

Map<String, Set<String>> courseTeacherMap = {c1: [t1], c2:[t2], c3:[t1, t2]}
Map<String, Set<String>> teacherStudentMap = {t1: [s1], t2:[s1, s2]}

结果应为*(student,course)表示以下示例中的courseStudentPair对象*

Set<courseStudentPair> result = [(c1, s1), (c2, s1), (c2, s2), (c3, s1), (c3, s2)]

使用for循环来完成它非常简单,但是我正在学习Java 8中的流函数,这对我来说似乎很复杂。您可以假设courseStudentPair类已定义构造函数或构建器。

2 个答案:

答案 0 :(得分:2)

本着同样的精神,您可以生成(课程,教师)的每个组合,然后查找与该教师相关的学生。这可能会生成重复项(例如(c3,s1)),因此请确保您的CourseStudentPair类基于这两个字段实现equals()hashCode()

import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.toSet;

...

Set<CourseStudentPair> result =
    courseTeacherMap.entrySet()
                    .stream()
                    .flatMap(e -> e.getValue()
                                   .stream()
                                   .flatMap(t -> teacherStudentMap.getOrDefault(t, emptySet()).stream().map(s -> new CourseStudentPair(e.getKey(), s))))
                    .collect(toSet());
/*
 Output:

 CourseStudentPair{studentName='c1', courseName='s1'}
 CourseStudentPair{studentName='c2', courseName='s2'}
 CourseStudentPair{studentName='c2', courseName='s1'}
 CourseStudentPair{studentName='c3', courseName='s2'}
 CourseStudentPair{studentName='c3', courseName='s1'}
*/

答案 1 :(得分:1)

List<Pair<String, String>> result = courseTeacherMap.entrySet()
            .stream()
            .flatMap(entry -> Optional.ofNullable(entry.getValue())
                    .orElse(new HashSet<>())
                    .stream()
                    .flatMap(teacher -> Optional.ofNullable(teacherStudentMap.get(teacher))
                            .orElse(new HashSet<>())
                            .stream()
                            .map(student -> Pair.of(entry.getKey(), student))))
            .distinct()
            .collect(Collectors.toList());

如果教师没有学生,或者你的Map可能有一个映射为null的键,我编辑它是为了使其安全无效。