java - 使用 Java 8 过滤流后收集

标签 java java-stream

我有一个 DTO 列表,这些 dto 包含一个标签列表。我正在寻找包含 2 个标签的 dto,每个标签都有自己的键和值。这段代码可以工作 - 但它只会在内部过滤器上找到第一个,我想收集而不是找到第一个,以防有多个具有该条件的对象

List<myDTO> responsesList = getAllData(parameters);
List<myDTO> result = responsesList.stream()
                    .filter(d ->
                            d.getData().getTags().stream()
                                .filter(t ->  t.getKey().equals(key1) && t.getValue().equals(value1))
                                .findFirst().isPresent())
                    .filter(d ->
                            d.getData().getTags().stream()
                                .filter(t -> t.getKey().equals(key2) && t.getValue().equals(value2))
                                .findFirst().isPresent())
                    .collect(Collectors.toList());

我在收集集合而不是 findFirst().isPresent() 时缺少什么?如果我这样做 Collect(collectors.toList) 我会收到一条错误消息,例如“推断变量 T 具有不兼容的边界”?

最佳答案

目前还不清楚你想要什么。如果您需要收集所有同时具有 key1/value1 标签和 key2/value2 标签的 myDTO 对象,那么您的代码已经可以工作了。您可以缩短它,因为 filter(predicate).findFirst().isPresent() 可以替换为 anyMatch(predicate):

List<myDTO> result = responsesList.stream()
                .filter(d ->
                        d.getData().getTags().stream()
                            .anyMatch(t -> t.getKey().equals(key1) && t.getValue().equals(value1)))
                .filter(d ->
                        d.getData().getTags().stream()
                            .anyMatch(t -> t.getKey().equals(key2) && t.getValue().equals(value2)))
                .collect(Collectors.toList());

您还可以将两个过滤器连接到单个谓词中,尽管这是一个品味问题:

List<myDTO> result = responsesList.stream()
                .filter(d ->
                        d.getData().getTags().stream()
                            .anyMatch(t -> t.getKey().equals(key1) && t.getValue().equals(value1))
                        &&
                        d.getData().getTags().stream()
                            .anyMatch(t -> t.getKey().equals(key2) && t.getValue().equals(value2)))
                .collect(Collectors.toList());

如果你确实想收集匹配的标签,你可能需要一个flatMap:

List<myTag> result = responsesList.stream()
                .flatMap(d -> d.getData().getTags().stream())
                .filter(t -> t.getKey().equals(key1) && t.getValue().equals(value1) ||
                             t.getKey().equals(key2) && t.getValue().equals(value2))
                .collect(Collectors.toList());

关于java - 使用 Java 8 过滤流后收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36336944/

相关文章:

java - 如何通过 WSO2(API 管理器)将自定义授权 header 传递到我的后端 Websocket 服务?

java - 在 Java Apache POI 中读取 Excel 复选框值

java - AutoCompleteTextView 未按预期工作

Java Stream按一个属性分组并按另一个属性收集最大元素

orm - 在没有 UI 的情况下配置 Speedment?

Java通用通配符构造函数不接受对象?

java - 确定集合中的元素编号 : handling null and zero element

java - 使用流操作从 String 中找到最小和最大的子串

Java 8 Streams - 分组为单个值

java - 从 Object[] 映射到自定义对象。使用 findBy SQL 查询