使用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");
Run Code Online (Sandbox Code Playgroud)
我希望根据集合过滤来自集合persons的项目names,这样只有那些指定了其名称的人才names会被保留,但是按照它们出现的顺序names.
所以,我想要
Set<Person> filteredPersons = ...;
Run Code Online (Sandbox Code Playgroud)
第一个元素是Person("B", 27)第二个元素Person("A", 23).
如果我这样做,
Set<Person> filteredPersons = new HashSet<>(persons);
filteredPersons = filteredPersons.stream().filter(p -> names.contains(p.getName())).collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)
names如果我没有记错的话,订单不能保证与in相同.
我知道如何使用简单的for循环来实现这一点; 我只是在寻找一种java 8方式.
谢谢你的期待!
编辑:
该用于循环,达到相同的结果:
Set<Person> filteredPersons = new LinkedHashSet<>();
for (String name : names) {
for (Person person : persons) {
if (person.getName().equalsIgnoreCase(name)) {
filteredPersons.add(person);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
该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));
Run Code Online (Sandbox Code Playgroud)
收集通过每个名称过滤它们创建的人员流.这对于所提供的示例的情况来说很快,但是会随着人数线性地缩放,例如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));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6584 次 |
| 最近记录: |