Неверный тип возврата в лямбда-выражении. Строка не может быть преобразована в объект - PullRequest
0 голосов
/ 26 декабря 2018

Мне нужно объединить данные, если возникнут дубликаты.Но не могу этого сделать.

Возможно ли в этом случае преобразовать строку в объект или объединить эти данные другим выражением?

У меня есть проблема: (a, b) -> a + ", " + b как Неверный тип возврата в лямбда-выражении. Строка не может быть преобразована в тему

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

1 Ответ

0 голосов
/ 26 декабря 2018

Перво-наперво, (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(", "))));
...