java - 通过使用条件嵌套的列表元素将其与另一个列表匹配来过滤对象

标签 java java-8 java-stream

我正在尝试使用 Java8 流过滤和收集具有条件的对象

我有一个实例列表,它有一个嵌套的元素列表

public class Model {
List<Instance> instances;
}
public class Instance {
private String name;
List<Element> elements;
}
public class Element {
private String partNumber;
}

下面是例子josn

{
    "instances": [
        {
            "name": "instance1",
            "elements": [
                {
                    "partNumber": "partNumber1"
                },
                {
                    "partNumber": "partNumber2"
                }
            ]
        },
        {
            "name": "instance2",
            "elements": [
                {
                    "partNumber": "partNumber3"
                },
                {
                    "partNumber": "partNumber4"
                }
            ]
        }
    ]
}

和其他响应对象

public class Response {
private List<Domain> domains;
}
public class Domain {
private String name;
private List<Hardware> hardwares;
}
public class Hardware {
private String partNumber;
}

样本 json

{
    "domains": [
        {
            "name": "domain1",
            "hardwares": [
                {
                    "partNumber": "partNumber1"
                }
            ]
        },
        {
            "name": "domain2",
            "hardwares": [
                {
                    "partNumber": "partNumber2"
                },
                {
                    "partNumber": "partNumber3"
                },
                {
                    "partNumber": "partNumber4"
                }
            ]
        },
        {
            "name": "domain3",
            "hardwares": [
                {
                    "partNumber": "partNumber5"
                },
                {
                    "partNumber": "partNumber6"
                }
            ]
        }
    ]
}

我正在尝试通过比较来自域的 Hardwares 是否至少包含来自请求的每个元素的 partnumber 来流式传输和收集响应对象。这意味着每个 Instance 中至少有一个 hardware 应该出现在 Domains hardware 中,以考虑 Domain 作为有效代码。

对于上面的示例数据,

  1. domain1 不是有效域,因为它至少包含 一个 partnumber partNumber1 来自 instance1 但不包含 至少一个 partnumber 来自 instance2
  2. domain2 是有效的 域,因为它至少包含一个 partnumber partNumber2 来自 instance1 并包含至少一个 partnumber partNumber3 来自 instance2。它可以包含其他零件号,即 好的
  3. domain3 不是有效域,因为它不包含 至少一个来自 instance1partnumber 并且不包含 至少一个来自 instance2
  4. partnumber

我开始写了

request.getInstances().stream().flatMap(instance -> instance.getElement().stream().filter(element -> response.getDomains().stream().flatMap(domain -> domain.getHardwares.stream().anyMatch(hardware-> element.contains()

但是由于我对流的理解有限,所以我很难完成这个

最佳答案

您可能可以在一个流中完成所有操作,但我建议使用两个流。首先,从模型中生成一组零件名称列表;然后,通过响应流式传输以查找域,这样对于每个实例,该实例的部件名称集中包含来自该域的某个部件名称。

List<Set<String>> parts = model.getInstances().stream()
        .map(i -> i.getElements().stream()
                .map(Element::getPartNumber)
                .collect(Collectors.toSet()))
        .collect(Collectors.toList());

response.getDomains().stream()
        .filter(d -> parts.stream()
                .allMatch(p -> d.getHardwares().stream()
                        .map(Hardware::getPartNumber)
                        .anyMatch(p::contains)))
        .forEach(System.out::println);

关于您的评论:现在,如果有一个没有元素的实例,这应该会删除所有域,因为 allMatch 将对该实例失败。相反,如果没有元素的实例应该被忽略,您可以将另一个 filter 添加到第一个流以创建 parts 列表(未测试):

        .filter(i -> ! i.getElements().isEmpty())

或者可能是 i.getElements() != null,具体取决于它的初始化方式。

关于java - 通过使用条件嵌套的列表元素将其与另一个列表匹配来过滤对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56688050/

相关文章:

java - 使用列表子集的组合生成列表,Java

Java 8 流 - 在平面图之后引用原始流对象

java - 如何将一个int按数字转换为数组数字

java - 从并行流中捕获异常

java - 由 : org. apache.maven.plugin.PluginContainerException 引起:

java - jQuery - AJAX 调用 Java 后端系统并刷新 html 列表

Java8 Lambda 反序列化 - ClassCastException

java - 流过滤/减少重复条目

C# 类类似于 Java Desktop 类

java - mac终端java错误解读