I would like to make my code more generic. And in order to achieve that, I proved as method parameters both a list and a supplier.
It turns out that reduce() cannot infer specific method in case where there are multiple to choose (see screenshot below).
How do I declare the method-version I would like to use?
public BigDecimal methodCalculate(List<MyObject> list, Supplier<? extends BigDecimal> getValue) {
BigDecimal sum = list.stream()
.filter(item -> item.getPremium())
.map(item -> getValue)
.reduce(BigDecimal.ZERO, BigDecimal::add);
return sum;
}

There are two issues I see in the code:
mapoperation creates a stream ofSupplier, notBigDecimal. Probably your intention was to use the supplier:Supplieris of typeSupplier<? extends BigDecimal>therefore with the fix above you would have a streamStream<? extends BigDecimal>, not a streamStream<BigDecimal>.Note: that there's no need to do anything special to make the compiler resolve the method reference
BigDecimal::addbecause only one overloaded version ofadd()is applicable based on the number of arguments. This reference should be classified as a reference to an instance method of a particular object because it represents an implementation ofBinaryOperator<BigDecimal>, which expects two arguments of typeBigDecimal, i.e. the method would be invoked on the first parameter of the operator and the second would serve as an argument. And there's only one version ofadd()expecting a single argument, the flavor ofadd()that takes aMathContextas an additional parameter isn't applicable here (for more information on method references, see).But although method
add()is accessible with the hypothetical subtype ofBigDecimaland compiler is capable to resolve the required version ofadd()the code would not compile.The flavor of reduce
reduce(identity,accumulator)should have exactly the same return type (which is the same as the identity type) as the type of elements in the stream. But based on the provided identity return type ofreducewould beBigDecimal, meanwhile in the stream we have? extends BigDecimal. That would cause a compilation error.We can fix both bullet-points by changing the type of supplier to
Supplier<BigDecimal>, since there are no subtypes ofBigDecimalin JDK:If you can't change the type of the supplier, then you need another flavor of
reduce(identity,accumulator,combiner), which is capable to have an identity (i.e. return type as well) that differs from the type of elements in the stream: