首页 > 解决方案 > 在 Java 中流式传输可选嵌套列表的最有效方法是什么?

问题描述

我一直在这里查看类似的问题,但没有一个可以帮助我解决这个特定问题。

我有一个包含列表列表的复杂嵌套对象:

class Container {
    private List<Foo> fooList;
}

class Foo {
    private List<Bar> barList;
}

class Bar {
    private List<Baz> bazList;
}

当我使用 REST api 时,我会返回一个 Container 对象,我希望它只有一个Baz实例。一旦我到达我的 Baz 对象,我需要评估一个谓词。我需要在遍历过程中防止空值。

这是我尝试过的:

 Optional.ofNullable(container)
                .map(Container::getFooList)
                .map(List::stream)
                .map(Stream::findFirst)
                .flatMap(Function.identity())
                .map(Foo::getBarList)
                .map(List::stream)
                .map(Stream::findFirst)
                .flatMap(Function.identity())
                .map(Bar::getBazList)
                .map(List::stream)
                .flatMap(Stream::findFirst)
                .map(Baz::getCode)
                .equals(someBaz.getCode());

现在,这可行,但看起来很糟糕,我认为必须有更好的方法。特别是,调用 identity 函数似乎是我在 findFirst 调用之后可以使用 flatMap 的唯一方法。

我怎样才能更简洁地做到这一点?

标签: javajava-stream

解决方案


您根本不需要身份功能。.map(f).flatMap(identity)是一样的.flatMap(f)

Optional.ofNullable(container)
    .map(Container::getFooList)
    .map(List::stream)
    .flatMap(Stream::findFirst)
    .map(Foo::getBarList)
    .map(List::stream)
    .flatMap(Stream::findFirst)
    .map(Bar::getBazList)
    .map(List::stream)
    .flatMap(Stream::findFirst)
    .map(Baz::getCode)
    .map(x -> x.equals(someBaz.getCode()))
    .orElse(false)

如果它在您的控制范围内,我还建议您制作任何给您Container返回 a 的东西Optional<Container>,而不必创建Optional<Container>内联。

此外,由于从不返回 null,您可以为 eachstream省略 a :mapgetXXXList

Optional.ofNullable(container)
    .map(Container::getFooList)
    .flatMap(x -> x.stream().findFirst())
    .map(Foo::getBarList)
    .flatMap(x -> x.stream().findFirst())
    .map(Bar::getBazList)
    .flatMap(x -> x.stream().findFirst())
    .map(Baz::getCode)
    .map(x -> x.equals(someBaz.getCode()))
    .orElse(false)

推荐阅读