簡體   English   中英

如何篩選包含列表的對象列表?

[英]How do I filter through a list of objects that contains lists?

想象一下,我有一個像下面這樣的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 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))));

而且,你正在尋找something

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中

返回一個流,該流包括將流中的每個元素替換為通過將提供的映射函數應用於每個元素而生成的映射流的內容而得到的結果。

基本上,您是嵌套流鏈接到一個流。

最后, findfirst方法返回第一個匹配項。 這意味着可能沒有匹配項,因此返回Optional Optional類具有用於檢索基礎對象並檢查其是否存在的方法( get()isPresent() )。 請查看Optional JavaDocs以獲取更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM