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 by getValueProvider()::apply if, and only if, the evaluation time of getValueProvider() 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) and System.out::println where reading the contents of the field System.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 like Function which has methods like andThen and/or compose. 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) where Y 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…
Answer from Holger on Stack OverflowYou 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 by getValueProvider()::apply if, and only if, the evaluation time of getValueProvider() 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) and System.out::println where reading the contents of the field System.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 like Function which has methods like andThen and/or compose. 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) where Y 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…
list.stream().sorted().collect(Collectors.toList()).forEach(element -> operate(element));
replace the above lambda with a method reference.
list.stream().sorted().collect(Collectors.toList()).forEach(this::operate);
java - How to replace a lambda with a method reference - Stack Overflow
[S1612] "Lambdas should be replaced with method references" should not be suggested if it would result in longer code
lambda x method reference taste
Suggestion to replace lambda with method reference causes invalid code (java:S1612)
Videos
I was able to solve the issue by assigning the type of the node which is in my case CmisObject as following:
childrenNames = StreamSupport.stream(favouritesFolder.getChildren().spliterator(), false)
.map(CmisObject::getName)
.limit(NUMBER_OF_FILES_TO_DISPLAY)
.collect(Collectors.toList());
node -> node.getName()=>Node::getName
Hello guys, I'm jr web back-end and during my "trainee introduction" one of my seniors and my job's SonarQube forced me to switch lambda expressions for method reference. I've searched a bit about this change wondering if all of this is about performance, or patterns or code reduction but I didn't find something solid, I know it's probably has been discussed here, but I want more opinions about. For me, lambda expression is way better to read and code, please don't judge me :D
You need to use the class name of the object being targeted by the stream. Example:
List<String> list = ...;
list.stream().collect(Collectors.groupingBy(String::toUpperCase));
so in your case:
FilterError::getUserId
In my case previously it was like this -
whitelist0.stream().filter(whitelistEntry -> !whitelistEntry.isEmpty()).map(s -> WhitelistEntry.of(s)).collect(Collectors.toList()));
As I need to pass a value to the function, so I did the following to replace the lambda with method reference -
whitelist0.stream().filter(whitelistEntry -> !whitelistEntry.isEmpty()).map(WhitelistEntry :: of).collect(Collectors.toList()));
You can't put Integer::toString because Integer has two implementations that fit to functional interface Function<Integer, String>, but you can use String::valueOf instead:
Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList())
It's ambiguous because the static and non-static toString() methods are both compatible with the functional signature Integer -> String. You can use String::valueOf instead.
So. Turns out there's a subtle difference between lambdas and method references. For instance, compare: myInstance::getStuff and () -> myInstance.getStuff()
This will mostly be considered equivalent. But. If myInstance happens to be null, the lambda will throw a null pointer when the lambda gets evaluated, but the method reference will throw right away when trying to access the reference.
So what? Well. This IS important if the code evaluating the lambda is inside a null-pointer try-catch.
Say I have a function mightBeNull(Supplier<T> function) that does something along the lines of:
try {
doStuff(function.get().getSomeMore().getSomeMore());
} catch (NullPointerException e) {
doOtherStuff();
}
If so. The call: mightBeNull(() -> myNullVariable.getStuff()) will work without exceptions, but the "equivalent": mightBeNull(myNullVariable::getStuff) will throw a null pointer exception right att the function call.