假设有Person
类看起来像这样:
public class Person {
private int id;
private String discriminator;
// some other fields plus getters/setters
}
现在我有Stream
个Person
元素,该流可能包含多个Person
个实例,这些实例具有相同的id
但不同的discriminator
值,即[Person{“id”: 1, “discriminator”: “A”}, Person{“id”: 1, “discriminator”: “B”}, Person{“id”: 2, “discriminator”: “A”}, ...]
我想要做的是过滤掉所有具有某个id的Person
个实例,如果至少有一个Person
实例具有该ID具有特定的鉴别值。因此,继续上面的例子,通过鉴别器值“A”过滤将产生一个空集合(当然,在还原操作之后)并且通过鉴别器值“B”过滤将产生不包含任何Person
实例的集合id等于1。
我知道我可以使用groupingBy
收集器和组元素按Person.id
减少流,然后如果映射列表包含Map
,则从结果Person
中删除映射具有指定鉴别值的元素,但我仍然想知道是否有更简单的方法来实现相同的结果?
答案 0 :(得分:3)
如果我理解你的问题,你会首先找到与鉴别器匹配的所有QIcon
:
ID
然后删除与这些条目匹配的条目:
Set<Integer> ids = persons.stream()
.filter(p -> "A".equalsIgnoreCase(p.getDiscriminator()))
.map(Person::getId)
.collect(Collectors.toSet())
答案 1 :(得分:1)
Eugenes的答案很有效,但我个人更喜欢单一的陈述。所以我把他的代码整理成一个单独的操作。看起来像这样:
final List<Person> result = persons.stream()
.filter(p -> "B".equalsIgnoreCase(p.getDiscriminator()))
.map(Person::getId)
.collect(
() -> new ArrayList<>(persons),
( list, id ) -> list.removeIf(p -> p.getId() == id),
( a, b ) -> {throw new UnsupportedOperationException();}
);
可能需要提一下,persons
的副本是必需的,否则Stream会损坏并遇到null
个值。
SideNote :当尝试并行使用时,此版本目前正在抛出
UnsupportedOperationException
。
答案 2 :(得分:1)
所以下面我提出了我想出的解决方案。首先,我通过Person.id属性对输入Person集合/流进行分组,然后我对映射条目进行流式处理,并过滤掉至少有一个与给定鉴别器匹配的值的那些。
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(
new Person(1, "A"),
new Person(1, "B"),
new Person(1, "C"),
new Person(2, "B"),
new Person(2, "C"),
new Person(3, "A"),
new Person(3, "C"),
new Person(4, "B")
);
System.out.println(persons);
System.out.println(filterByDiscriminator(persons, "A"));
System.out.println(filterByDiscriminator(persons, "B"));
System.out.println(filterByDiscriminator(persons, "C"));
}
private static List<Person> filterByDiscriminator(List<Person> input, String discriminator) {
return input.stream()
.collect(Collectors.groupingBy(Person::getId))
.entrySet().stream()
.filter(entry -> entry.getValue().stream().noneMatch(person -> person.getDiscriminator().equals(discriminator)))
.flatMap(entry -> entry.getValue().stream())
.collect(Collectors.toList());
}
}
class Person {
private final Integer id;
private final String discriminator;
public Person(Integer id, String discriminator) {
Objects.requireNonNull(id);
Objects.requireNonNull(discriminator);
this.id = id;
this.discriminator = discriminator;
}
public Integer getId() {
return id;
}
public String getDiscriminator() {
return discriminator;
}
@Override
public String toString() {
return String.format("%s{\"id\": %d, \"discriminator\": \"%s\"}", getClass().getSimpleName(), id, discriminator);
}
}