如果出现重复,我需要连接数据。但做不到。
在这种情况下,是否可以将字符串转换为对象或通过另一个表达式联接该数据?
我在那里有一个问题:(a, b) -> a + ", " + b
lambda 表达式中的返回类型错误 字符串无法转换为主题
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()));
这是标记列表:
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
,(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(", "))));