Java-потоки объединяют два списка - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть HashSet of Persons.У человека есть имя, фамилия и возраст, например: Person («Ганс», «Мужчина», 36)

Моя задача - получить список людей старше 17 лет, отсортировать их по возрасту иконкатенируйте firstName с lastName, например: ["Hans Man", "другое имя", "другое имя"]

Мне разрешено импортировать:

import java.util.stream.Stream; import java.util.stream.Collectors; import java.util.List; import java.util.ArrayList;

Моя идея состояла в том, чтобы сначала отсортировать их, сопоставить имена в отдельных потоках и сжать их, но это не работает.

public static void getNamesOfAdultsSortedByAge(Stream<Person> stream){

    Stream<Person> result = stream;
    Stream<Person> result1 = result.filter(p -> p.getAge() >= 18)
                            .sorted((x, y) -> Integer.compare(x.getAge(),y.getAge()));


    Stream<String> firstName = result1.map(Person::getFirstName);
    Stream<String> lastName = result1.map(Person::getLastName);

    Stream<String> result3 = concat(firstName, lastName);

    List<String> result4 = result3.collect(Collectors.toList());

    System.out.println(result4);
}

заранее спасибо

Ответы [ 5 ]

0 голосов
/ 29 ноября 2018

Я бы использовал следующее, и, поскольку у вас есть странные правила, касающиеся импорта, я скрываю его за Comparator сознательно:

List<String> result = stream.filter(p -> p.getAge() >= 18)
                            .sorted(java.util.Comparator.comparingInt(Person::getAge))
                            .map(p -> p.getFirstName() + " " + p.getLastName())
                            .collect(Collectors.toList());

Примечание: я знаю о некоторых правилахэто означает, что не следует использовать никакую другую зависимость, кроме той, которая указана в «разрешенном списке зависимостей», но я никогда не слышал о правиле, которое позволяет использовать только 4 импорта, но запрещает один из самых важных.Если бы Comparator был бы внутренним интерфейсом / классом, я мог бы понять это, но это существенный интерфейс.Вы даже используете его как функциональный интерфейс, если пишете (x, y) -> Integer.compare(x.getAge(),y.getAge()), поэтому я действительно не понимаю, почему этот импорт не должен быть разрешен.При этом, мое решение не требует, чтобы вы использовали импорт в java.util.Comparator.Получайте удовольствие, используя его.Это действительно делает сравнение проще и менее подвержено ошибкам (представьте себе два метода с одинаковыми именами, и вы ошиблись в поиске неправильного ... получайте удовольствие, находя эту ошибку; -)).

0 голосов
/ 29 ноября 2018

Вы можете сделать это, используя:

public static void getNamesOfAdultsSortedByAge(Stream<Person> stream) {
    List<String> sorted = stream.filter(p -> p.getAge() >= 18)
                                .sorted((x, y) -> Integer.compare(x.getAge(),y.getAge()))
                                .map(e -> e.getFirstName() + " " + e.getLastName())
                                .collect(Collectors.toList());
    System.out.println(sorted);
}

Здесь мы просто map отсортируем поток, объединяя имя, а затем фамилию, после чего мы используем операцию терминала .collect() для сбораэто к списку.

0 голосов
/ 29 ноября 2018

Внутри getNamesOfAdultsSortedByAge метод:

stream
    .filter(p -> p.getAge() > 17)
    .sorted(Comparator.comparingInt(Person::getAge))
    .map(person -> person.getFirstName() + " " + person.getLastName())
    .collect(Collectors.toList())

Полагаю, это должно соответствовать вашим потребностям.filter фильтрует людей старше 18 лет, вторая строка сортируется с помощью предиката getAge, третья просто отображает Person экземпляр в строку, содержащую %firstName% %lastName%, а четвертая собирает результат в список.

0 голосов
/ 29 ноября 2018
public static void main(String[] args) {
    final List<String> matching = Lists.newArrayList(
            new Person("Joey", "Tribiani", 28),
            new Person("Rachel", "Green", 12),
            new Person("Ross", "Geller", 114),
            new Person("Chandler", "Bing", 17)).stream()
            .filter(person -> person.getAge() > 17)
            .sorted(Comparator.comparing(Person::getAge))
            .map(person -> person.getFirstName() + " " + person.getLastName())
            .collect(toList());
}

Если вам нужно изменить порядок сортировки, просто измените компаратор:

Comparator.comparing(Person::getAge).reversed()
0 голосов
/ 29 ноября 2018

Это не работает:

Stream<String> firstName = result1.map(Person::getFirstName);
Stream<String> lastName = result1.map(Person::getLastName);

После первого map, Stream имеет тип String, который не подходит Person::getLastName.Вам нужно выполнить конкат в первом же вызове map().

...