Reputation: 8837
I have this current logic:
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());
Where in IntelliJ the flatMap
part is highlighted and shows the following error hint:
no instance(s) of type variable(s) U exist so that Stream<ProductPrice> conforms to Optional<? extends U>
I know that Optionals
and Stream
are two different things but I wonder if there is a way to combine them so I can follow up an Optional<List<?>>
with a Stream
afterwards.
Upvotes: 2
Views: 143
Reputation: 31868
An alternate solution would be to get the value of the Optional
using orElse
and this can be done without upgrading to Java-9. It would look like:
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());
Upvotes: 1
Reputation: 45309
If you're on Java 9+, you can use Optional.stream
, followed by flatMap
:
ofNullable(product.getProductPrices())
.map(ProductPrices::getProductPrices)
.stream()
.flatMap(Collection::stream) //assuming getProductPrices returns a Collection
...
Optional.stream
returns an empty stream if the optional is empty.
Upvotes: 2
Reputation: 393781
Since you are starting with an Optional
, you have to decide what to return when that Optional
is empty.
One way is to put the Stream
pipeline inside the Optional
's map
:
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);
Or course, if the map
operations inside the Stream
pipeline may return null
, additional changes will be required (to avoid NullPointerException
).
On the other hand, if they can never return null
, they can be chained into a single 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);
Upvotes: 2