简体   繁体   English

使用Java 8过滤流后收集

[英]Collecting after filtering a stream with Java 8

i have a list of DTOs, these dtos contains a list of tags. 我有一个DTO列表,这些dto包含一个标签列表。 I'm searching to find dtos that contain 2 tags each with its own key and value. 我正在寻找包含2个标签的dto,每个标签都有自己的键和值。 this code will work - but it would only find first on the inner filters, i would like to collect instead of finding the first, in case there is more than one object with that criteria 该代码将起作用-但它只会首先在内部过滤器上找到,我想收集而不是首先找到,如果存在多个符合该条件的对象

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());

what am I missing to collect a collection instead of the findFirst().isPresent() ? 我缺少什么来收集集合而不是findFirst().isPresent() if I do Collect(collectors.toList) I get an error message like "inference variable T has incompatible bounds"? 如果我执行Collect(collectors.toList)则会收到类似“推断变量T具有不兼容边界”的错误消息?

It's not actually clear what do you want. 实际上还不清楚您想要什么。 If you need to collect all the myDTO objects which have both key1/value1 tag and key2/value2 tag, then your code already works. 如果您需要收集同时具有key1 / value1标签和key2 / value2标签的所有myDTO对象,则您的代码已经可以使用。 You can just shorten it as filter(predicate).findFirst().isPresent() could be replaced with anyMatch(predicate) : 您可以将其缩短为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());

You can also join both filters into single predicate, though this is a matter of taste: 您也可以将两个filters合并为单个谓词,尽管这是一个问题:

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());

If you actually want to collect matching tags, you may need a flatMap : 如果您实际上想收集匹配的标签,则可能需要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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM