gpt4 book ai didi

Java 8 Filter 集基于另一集

转载 作者:搜寻专家 更新时间:2023-10-31 08:25:36 27 4
gpt4 key购买 nike

使用 Java 8 新构造,例如流,是否有办法根据另一个集合中的顺序过滤 Set

Set<Person> persons = new HashSet<>();

persons.add(new Person("A", 23));
persons.add(new Person("B", 27));
persons.add(new Person("C", 20));

List<String> names = new ArrayList<>();
names.add("B");
names.add("A");

我想根据 names 从集合 persons 中过滤项目,这样只有那些在 names 中指定了名字的人才会被过滤保留,但按照它们在 names 中出现的顺序。

所以,我想

Set<Person> filteredPersons = ...;

第一个元素是 Person("B", 27),第二个元素是 Person("A", 23)

如果我执行以下操作,

Set<Person> filteredPersons = new HashSet<>(persons);
filteredPersons = filteredPersons.stream().filter(p -> names.contains(p.getName())).collect(Collectors.toSet());

如果我没记错的话,不能保证顺序与 names 中的顺序相同。

我知道如何使用简单的 for 循环实现此目的;我只是在寻找一种 Java 8 的实现方式。

感谢您的关注!

编辑:

实现相同结果的 for 循环:

Set<Person> filteredPersons = new LinkedHashSet<>();
for (String name : names) {
for (Person person : persons) {
if (person.getName().equalsIgnoreCase(name)) {
filteredPersons.add(person);
break;
}
}
}

LinkedHashSet 实现确保顺序得到维护。

最佳答案

final Set<Person> persons = ...
Set<Person> filteredPersons = names.stream()
.flatMap(n ->
persons.stream().filter(p -> n.equals(p.getName()))
)
.collect(Collectors.toCollection(LinkedHashSet::new));

通过按每个名字过滤创建的人员流,收集这些人员流。对于提供的示例这样的情况,这很快,但会随着人数线性扩展,例如 O(N*P)。

对于较大的人员和姓名集合,创建可用于按姓名查找人员的索引总体上会更快,缩放为 O(N+P):

Map<String, Person> index = persons.stream()
.collect(Collectors.toMap(Person::getName, Function.identity()));
Set<Person> filteredPersons = names.stream()
.map(index::get)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(LinkedHashSet::new));

关于Java 8 Filter 集基于另一集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34728677/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com