如果重复将发生,我需要合并数据。但是不能这样做。
在这种情况下,是否可以将String转换为Object或通过另一个表达式连接该数据?
我在这里遇到问题:(a, b) -> a + ", " + b
为
lambda表达式字符串中的错误返回类型不能转换为Subject
Map<Student, Subject> result = markList
.stream()
.collect(Collectors.toMap(
Mark::getStudent,
Mark::getSubject,
(a, b) -> a + ", " + b));
result.forEach((student, subject) ->
System.out.printf("%s %s : %s ", student.getFirstName(),
student.getLastName(), subject.getName()));
这是markList:
List<Mark> markList = new ArrayList<>();
markList.add(new Mark(student_1, subject_1, 1));
markList.add(new Mark(student_1, subject_2, 2));
markList.add(new Mark(student_2, subject_1, 1));
并希望获得加入的主题数据,以防发现重复
预期输出:
[student_1
与subject_1
,subject_2
和
student_2
和subject_1
]:
John McDonald: Mathematics, Astronomy
Kira Wild: Mathematics
================================================ ======
但是
这段代码可以不重复地工作,例如:(a, b) -> a
输出:
John McDonald: Mathematics
Kira Wild: Mathematics
答案 0 :(得分:3)
首先,(a, b) -> a + ", " + b)
不会仅仅因为返回的值必须是Subject
而不是String
而编译,我相信鉴于您的最新编辑状态,您最终已经弄清楚了使用(a, b) -> a
合并功能时,代码现在可以正常工作了。
在最新更新中未获得预期结果的原因是,您正在使用合并功能(a, b) -> a
,意思是“如果两个给定的科目具有相同的学生,则保留第一个学生并丢弃该学生。第二”。
相反,您想要做的是以某种方式维持这两名学生,因此从本质上讲,您将拥有Map<Student, List<Subject>>
。
这可以通过以下方式完成:
Map<Student, List<Subject>> result = markList
.stream()
.collect(Collectors.toMap(
Mark::getStudent,
v -> new ArrayList<>(singletonList(v.getSubject())),
(a, b) -> {a.addAll(b); return a;}));
实际上,最好通过groupingBy
并以mapping
作为下游收集器来完成此操作:
Map<Student, List<Subject>> resultSet = markList.stream()
.collect(groupingBy(Mark::getStudent,
mapping(Mark::getSubject, toList())));
最后,您可以使用以下方法测试结果:
resultSet.forEach((student, subjects) ->
System.out.printf("%s %s : %s ", student.getFirstName(), student.getLastName(),
subjects.stream().map(Subject::getName).collect(joining(", "))));