Как использовать поток в java 8 для сбора нескольких полей в один список?

Например, у меня есть класс Person с именем и фамилией.

Я хочу собрать список строк (имена и фамилии вместе) из списка Person, но кажется, что я не могу использовать карту дважды в одном списке или не могу использовать поток дважды в списке. Мой код:

persons.stream()
 .map(Person::getName)
 .collect(Collectors.toSet())
 .stream().map(Person::getSurname) 
 .collect(Collectors.toList())

но он продолжает говорить мне, что нестатический метод Person::getSurname не может ссылаться на статический контекст.

Что я делаю неправильно?

Ответ 1

Чтобы получить имена и фамилии в одном списке, вы можете сделать это:

List<String> set = persons.stream()
  .flatMap(p -> Stream.of(p.getName(),p.getSurname()))
  .collect(Collectors.toList());

Ответ 2

Когда вы делаете:

persons.stream().map(Person::getName).collect(Collectors.toSet())

Результат: Set<String>, содержащий только name persons. Затем вы воссоздаете поток из этого Set, а не из List<Person> persons.

Вот почему вы не можете использовать Person::getSurname для сопоставления этого Set.

Решение от @Alexis C.: persons.stream().flatMap(p -> Stream.of(p.getName(), p.getSurname()).collect(Collectors.toSet()) должен выполнить задание.

Ответ 3

Ваш код должен выглядеть примерно так:

persons.stream()
.map(person -> person.getName() + " " + person.getSurname)
.collect(Collectors.toList());

Ответ 4

если человек имеет имя и отчество необязательно, используйте код ниже

return Stream.of(Optional.ofNullable(person)
.map(Person::getFirstName)
.orElse(null),
Optional.ofNullable(person)
.map(Person::getMiddleName)
.orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.joining(SPACE));