Получить подмножество из надмножества с помощью Java Streams

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

Скажем, у меня есть супер-список объектов "Человек", как показано ниже:

List<Person> personsList = new ArrayList<>();
personsList.add(new Person("John", 28));
personsList.add(new Person("Paul", 29));
personsList.add(new Person("Adam", 30));
personsList.add(new Person("Peter", 31));
personsList.add(new Person("Pat", 32));

Пусть класс Person определяется следующим образом:

class Person {
    public String name;
    public int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + ": " + age;
    }
}

Учитывая такой подсписок:

String [] names = {"John", "Paul", "Adam"};
List<String> namesList = Arrays.asList(names);

Я хотел бы получить объекты Person с именем John, Paul и Adam.

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

List<Person> finalList = personsList.stream().filter(p -> namesList.contains(p.name))
                .collect(Collectors.toCollection(() -> new ArrayList<Person>()));

Я получил желаемый результат, но хотел бы знать, есть ли какой-либо другой эффективный метод для достижения этого (я в основном смотрю на namesList.contains (p.name) как на немного неэффективный).

Пожалуйста, дайте мне знать, если есть лучший способ сделать это.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
835
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Определение nameList как Set будет более эффективным, хотя, если список содержит только 3 имени, разница действительно будет не заметна.

Так что-то вроде этого:

Set<String> namesList = new HashSet<> (Arrays.asList("John", "Paul", "Adam"));

List<Person> finalList = personsList.stream()
                                    .filter(p -> namesList.contains(p.name))
                                    .collect(Collectors.toList());

Примечание: я также изменил коллектор на toList, так как он, по-видимому, вам нужен.

Спасибо @assylias. Итак, моя основная идея использования "содержит" все еще хороша, хотя тогда я мог бы использовать Collectors.toList ().

Ravi 22.05.2018 11:08
Ответ принят как подходящий

Предположим, что нет смысла иметь повторяющиеся имена в массиве, лучший способ - найти имя в Set<T> имен. Этого легко добиться. Преобразуйте массив в список и включите его в конструктор HashSet<T>, как только он примет любую коллекцию.

String [] names = {"John", "Paul", "Adam"};
Set<String> set = new HashSet<>(Arrays.asList(names));

Теперь используйте Stream-API так же, как вы пробовали. Используйте только статический метод Collectors.toList().

List<Person> list= personsList.stream()
    .filter(i -> set.contains(i.getName()))
    .collect(Collectors.toList());

Результат будет содержать только объекты лиц John, Paul и Adam.

Спасибо, @Nikolas. Итак, моя основная идея использования "содержит" все еще хороша, хотя тогда я мог бы использовать Collectors.toList (). Кроме того, я считаю, что это опечатка в вашем ответе, когда говорится, что результат будет содержать только объекты «Питер» и «Пэт»?

Ravi 22.05.2018 11:08

Я редактировал это. Это, конечно, было моей бедой. :) Stream :: filter возвращает Stream с элементами, соответствующими заданному предикату.

Nikolas Charalambidis 22.05.2018 12:13

Другие вопросы по теме