如何在 Java 中将可选映射转换为流映射

How to translate a Optional mapping to Stream mapping in Java

我目前的逻辑是:

    List<String> priceUnitCodes = ofNullable(product.getProductPrices())
            .map(ProductPrices::getProductPrices)
            .flatMap(productPrices -> productPrices.stream()) // << error highlight
            .map(ProductPrice::getPriceBase)
            .map(PriceBase::getPriceUnit)
            .map(UniversalType::getCode)
            .collect(Collectors.toList());

在 IntelliJ 中,flatMap 部分被突出显示并显示以下错误提示:

no instance(s) of type variable(s) U exist so that Stream<ProductPrice> conforms to  Optional<? extends U>

我知道 OptionalsStream 是两个不同的东西,但我想知道是否有办法将它们结合起来,这样我就可以在 Optional<List<?>> 之后跟进 [=15] =] 之后。

由于您是从 Optional 开始的,因此当 Optional 为空时,您必须决定要 return 什么。

一种方法是将 Stream 管道放在 Optionalmap 中:

List<String> priceUnitCodes = ofNullable(product.getProductPrices())
        .map(ProductPrices::getProductPrices)
        .map(productPrices -> productPrices.stream()
                                           .map(ProductPrice::getPriceBase)
                                           .map(PriceBase::getPriceUnit)
                                           .map(UniversalType::getCode)
                                           .collect(Collectors.toList())
        .orElse(null);

或者当然,如果 Stream 管道内的 map 操作可能 return null,则需要进行额外的更改(以避免 NullPointerException) .

另一方面,如果它们永远无法 return null,则可以将它们链接成一个 map:

List<String> priceUnitCodes = ofNullable(product.getProductPrices())
        .map(ProductPrices::getProductPrices)
        .map(productPrices -> productPrices.stream()
                                           .map(pp -> pp.getPriceBase().getPriceUnit().getCode())
                                           .collect(Collectors.toList())
        .orElse(null);

如果您使用的是 Java 9+,您可以使用 Optional.stream,然后是 flatMap:

ofNullable(product.getProductPrices())
.map(ProductPrices::getProductPrices)
.stream()
.flatMap(Collection::stream) //assuming getProductPrices returns a Collection
...

Optional.stream returns 如果可选项为空,则为空流。

另一种解决方案是使用 orElse 获取 Optional 的值,这可以在不升级到 Java-9 的情况下完成。它看起来像:

List<String> priceUnitCodes = Optional.ofNullable(product.getProductPrices())
            .map(ProductPrices::getProductPrices)
            .orElse(Collections.emptyList()) // get the value from Optional
            .stream()
            .map(ProductPrice::getPriceBase)
            .map(PriceBase::getPriceUnit)
            .map(UniversalType::getCode)
            .collect(Collectors.toList());