This code sample
Collection<Number> values = transform(
getValuatedObjects(),
input -> getValueProvider().apply(input).getValue());
violates the sonarqube rule:
Replace lambdas with method references when possible
is it a sonar bug ? or can i really use a method reference ?
if you are coding in java 8 you can use method reference in place of lambda expression for code readable
replace this lambda with a method reference
Replace
You can’t replace the lambda
input -> getValueProvider().apply(input).getValue()
with a method reference without changing the semantics.A method reference replace a single method invocation, so it can’t simply replace a lambda expression consisting of more than one method invocation.
A lambda expression of the form
input -> getValueProvider().apply(input)
could be replaced bygetValueProvider()::apply
if, and only if, the evaluation time ofgetValueProvider()
does not matter as in the lambda form the method is invoked on each lambda body evaluation while for the method reference it is invoked only once and the result captured.This is similar to the difference between
x -> System.out.println(x)
andSystem.out::println
where reading the contents of the fieldSystem.out
happens at different times but usually it doesn’t matter. But you should be aware of the difference.In your example, a third method
getValue()
is invoked. The only way to express that with method references needs a functional interface likeFunction
which has methods likeandThen
and/orcompose
. However, the way Java 8 works, that would require casting the first method reference to the target interface to invoke the combining method which would be by no way easier to read that the lambda expression you have now:((Function<X,Y>)getValueProvider()::apply).andThen(Y::getValue)
whereY
is the type,apply(input)
returns.Note that the rule says “Replace lambdas with method references when possible” which gives you room to say, “well, here it is impossible”, however, I’m not sure how much you can call it a “rule” then…