Извлечь подмножество из надмножества, используя потоки Java - PullRequest
0 голосов
/ 22 мая 2018

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

Допустим, у меня есть суперсписок объектов "Person" следующим образом:

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) как немного неэффективный).

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

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

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

0 голосов
/ 22 мая 2018

Определение nameList как набора будет более эффективным, хотя, если список содержит только 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, поскольку это то, что вам, очевидно, нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...