使用 Java Streams 从超集中获取子集

Rav*_*avi 1 java list arraylist java-8 java-stream

我需要从给定的超级列表中获取子列表,如下所述。

假设我有一个“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));
Run Code Online (Sandbox Code Playgroud)

让 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

给定这样的子列表:

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

我想获取名称为John,Paul和的 Person 对象Adam

我是 Java 流的新手,这是我迄今为止尝试满足我的要求的方法。

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

我得到了想要的结果,但我想知道是否有任何其他有效的方法来实现这一点(我主要是将 namesList.contains(p.name) 视为有点低效)。

请让我知道是否有更好的方法来做到这一点。

Nik*_*las 5

假设数组中有重复的名字是没有意义的,最好的方法是在 a Set<T>of names 中找到名字。这很容易实现。将数组转换为 List 并在HashSet<T>它接受任何集合后立即将其包含在 的构造函数中。

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

现在使用与您尝试过的相同的 Stream-API。仅使用静态方法Collectors.toList()

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

结果将只包含John,PaulAdam人的对象。