假设有一个 Person
类如下所示:
public class Person {
private int id;
private String discriminator;
// some other fields plus getters/setters
}
现在我有一个< code>Person元素的< code>Stream,该流可能包含多个< code>Person实例,这些实例具有相同的< code>id,但具有不同的< code>discriminator值,即< code>[Person{"id": 1," discriminator": "A"},Person{"id": 1," discriminator": "B"},Person{"id": 2," discriminator": "A"},...]
我想做的是,如果至少有一个具有某个id的Person
实例具有特定的鉴别器值,则过滤掉具有该id的所有Person
。因此,继续上面的示例,按鉴别器值“A”过滤将生成空集合(当然,在缩减操作之后),按鉴别符值“B”过滤将产生不包含任何id等于1的Person
实例的集合。
我知道我可以使用groupingBy
收集器和分组元素来减少
流,Person.id 然后如果映射的列表包含具有指定鉴别器值的Person
元素,则从生成的Map
中删除映射,但我仍然想知道是否有更简单的方法来实现相同的结果?
下面我将介绍我提出的解决方案。首先,我按人员对输入人员集合/流进行分组。id属性,然后我对映射条目进行流式处理,并过滤掉至少有一个值与给定鉴别器匹配的条目。
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);
}
}
尤金的答案很好,但我个人更喜欢单一的语句。所以我把他的代码放在一起,放入一个操作中。看起来像这样:
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();}
);
可能需要提到需要人
的副本,否则Stream将损坏并遇到null
值。
旁注:此版本在尝试并行使用时,当前会引发不受支持的操作异常
。
如果我正确地理解了您的问题,您将首先找到与鉴别器匹配的所有ID
:
Set<Integer> ids = persons.stream()
.filter(p -> "A".equalsIgnoreCase(p.getDiscriminator()))
.map(Person::getId)
.collect(Collectors.toSet())
然后删除与以下内容匹配的条目:
persons.removeIf(x -> ids.contains(x.getId()))
我正在寻找一种方法来声明“2个依赖项之间的依赖项”。 例如,在我的模块中,我ivy.xml以下行: 我的问题是,日志经典 1.0.13 依赖于 slf4j-api 1.7.5,而我的模块依赖于 1.6.6(slf4japiversion 的值)。 我无法更改 slf4japiversion,但将来它可以由其他人升级。 有没有办法声明对logback的依赖关系,以检索与我的slf4j api版本兼容
我有一个对象的集合,每个对象都有一个元素的集合,例如: 如何使用Java 8函数式编程来过滤和收集类型等于“a”的集合? 我尝试了以下方法: 但我得到以下错误: 变量'filteredChildren'初始值设定项'parents。stream()。forEach(p- 如何按类型筛选嵌套集合并收集它们?
问题内容: 我有计算纯python中相邻元素之间差异的算法: 有什么办法可以用Numpy重写此功能? 问题答案: 有方法: 退货
问题内容: 我有以下pandas数据框Top15:在此处输入图片说明 我创建了一个估计每人可引用文件数量的列: 我想知道人均引用文件数量与人均能源供应之间的相关性。因此,我使用该.corr()方法 (皮尔逊相关性): 问题答案: 没有实际数据,很难回答这个问题,但是我想您正在 寻找这样的东西: That calculates the correlation between your two col
我正在使用两个具有扁平数据结构的存储库,例如“MenuItemRepo”和“IngredEnterpo”。它们之间的关系结构是:一个菜单项可以包含许多成分,而一种成分(例如奶酪)可以是许多菜单项的一部分。数据库表的建模如下: > MenuItem表条目 字符串Menuitem-id 字符串名称... MenuItem成分参考表条目 字符串Menuitem-id 字符串成分ID 成分表条目 字符串成
我正在使用Jackson的JsonNode解析json。我的json结构如下所示(设为变量rawJson): 在Java中: 如何通过过滤属性<code>name</code>来获得特定的JsonNode元素?如果我想得到<code>值</code>大于X的JsonNode元素,怎么样?我是否可以在不遍历<code>结果</code>变量的情况下完成这些操作?