java - 如何过滤包含列表的对象列表?

标签 java filter java-8 java-stream

假设我有一个如下所示的 json:

[
    {
        field: string,
        roles: [
            {
                id: int,
                providedFor: int
            },
            {
                id: int,
                providedFor: int
            },
            ...
        ]
    },
    {
        field: string,
        roles: [
            {
                id: int,
                providedFor: int
            },
            {
                id: int,
                providedFor: int
            },
            ...
        ]
    },
    {
        field: string,
        roles: [
            {
                id: int,
                providedFor: int
            },
            {
                id: int,
                providedFor: int
            },
            ...
        ]
    }
]

这被解析为一个对象列表并调用这个列表提供者。 我该如何过滤/流式传输此列表,找到正确的提供商然后进行突破?

我尝试过类似以下的操作:

providers.parallelStream().filter(p -> p.getRoles().parallelStream().filter(r -> r.getProvidedFor.equal("something")).findFirst());

最佳答案

由于您没有提供任何类(class),我已经尝试了以下结构:

class Field {
    String field;
    List<Role> roles;

    Field(String field, List<Role> roles) {
        this.field = field;
        this.roles = roles;
    }
}

class Role {
    int id;
    int providedFor;

    Role(int id, int providedFor) {
        this.id = id;
        this.providedFor = providedFor;
    }
}

Field 是外部对象,Role 是内部对象。因此,如果您构建一个 Field 对象的 List,如下所示:

final List<Field> fields = Arrays.asList(
        new Field("f11", Arrays.asList(new Role(11, 11), new Role(11, 12))),
        new Field("f22", Arrays.asList(new Role(22, 22), new Role(22, 23))),
        new Field("f33", Arrays.asList(new Role(33, 33), new Role(33, 34))));

而且,您正在搜索某物:

int something = 22;

您可以使用 flatMap 方法过滤掉您的 Role,如下所示:

final Optional<Role> first = fields.stream()
        .flatMap(f -> f.roles.stream())          // Chain all "substreams" to one stream
        .filter(r -> r.providedFor == something) // Check for the correct object
        .findFirst();                            // Find the first occurrence

请注意,如果 providedFor 不是原语,而是某种 Object,则应使用 equals 方法。

如果您正在寻找 Field 类,您可以简单地嵌套流,如下所示:

final Optional<Field> firstField = fields.stream()
        .filter(f -> f.roles.stream()                       // Nested stream
                .anyMatch(r -> r.providedFor == something)) // Return true if present
        .findFirst();                                       // Find the first Field object (findAny can be used here as well if "any" hit is ok)

这将返回与提供的 Role.providedFor 匹配的第一个 Field

来自flatMap JavaDocs :

Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

基本上,您将嵌套流链接到一个流。

最后,findfirst 方法返回第一个匹配项。这意味着可能没有匹配项,因此返回 OptionalOptional 类具有检索底层对象并检查其是否存在的方法(get()isPresent())。查看Optional JavaDocs了解更多信息。

关于java - 如何过滤包含列表的对象列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28330763/

相关文章:

c - 在 C 中实现简单的高通和低通滤波器

sql - Oracle SQL - 过滤掉包含具有特定值的行的分区或行组

java - 如何获取 JavaFX 8 中 ScrollPane 内 Label 对象的位置

python - Python 中 signal.filtfilt 中的 Padlen 错误

Java 列表流 anyMatch 返回错误结果

java - Java 8 中抽象类对接口(interface)的偏好

java - 如何获取父类(super class)的this.getClass().getConstructor?

java - 根据主机名加载 Bean

java - 如何下载和安装 xuggler?

java - 自动填充组合框系列 - Java