Java 声纳:用方法引用替换这个 lambda
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25606906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sonar : Replace this lambda with a method reference
提问by gontard
This code sample
此代码示例
Collection<Number> values = transform(
getValuatedObjects(),
input -> getValueProvider().apply(input).getValue());
violates the sonarqube rule:
违反声纳规则:
Replace lambdas with method references when possible
尽可能用方法引用替换 lambda
is it a sonar bug ? or can i really use a method reference ?
这是声纳错误吗?或者我真的可以使用方法参考吗?
采纳答案by Holger
You can't replace the lambda input -> getValueProvider().apply(input).getValue()
with a method reference without changing the semantics.
您不能在input -> getValueProvider().apply(input).getValue()
不更改语义的情况下用方法引用替换 lambda 。
A method reference replace a singlemethod invocation, so it can't simply replace a lambda expression consisting of more than one method invocation.
方法引用替换了单个方法调用,因此它不能简单地替换由多个方法调用组成的 lambda 表达式。
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.
形式的 lambda 表达式input -> getValueProvider().apply(input)
可以被替换为getValueProvider()::apply
当且仅当, 的评估时间getValueProvider()
无关紧要,因为在 lambda 形式中,该方法在每个 lambda 主体评估中被调用,而对于方法引用,它仅被调用一次并且结果捕获。
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.
这类似于之间的区别x -> System.out.println(x)
,并System.out::println
在那里读字段的内容System.out
在不同的时间发生,但通常并不重要。但是你应该知道其中的区别。
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.
在您的示例中,getValue()
调用了第三个方法。使用方法引用来表达这一点的唯一方法需要一个功能接口,例如Function
具有andThen
和/或之类的方法compose
。但是,Java?8 的工作方式需要将第一个方法引用强制转换为目标接口以调用组合方法,这对于您现在拥有的 lambda 表达式来说绝不容易阅读:类型((Function<X,Y>)getValueProvider()::apply).andThen(Y::getValue)
在哪里Y
,apply(input)
返回。
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…
请注意,规则说“尽可能用方法引用替换 lambda ”,这让您有空间说,“好吧,这是不可能的”,但是,我不确定您可以将其称为“规则”到什么程度……
回答by Neeraj Gahlawat
if you are coding in java 8 you can use method reference in place of lambda expression for code readable
如果您在 Java 8 中编码,您可以使用方法引用代替 lambda 表达式以获得代码可读性
List<Integer> list = Arrays.asList(1,2,3,4,5);
replace this lambda with a method reference
用方法引用替换这个 lambda
strList.stream().sorted().collect(Collectors.toList()).forEach(s -> System.out.println(s));
Replace
代替
strList.stream().sorted().collect(Collectors.toList()).forEach(System.out::println);
回答by Akanksha gore
list.stream().sorted().collect(Collectors.toList()).forEach(element -> operate(element));
list.stream().sorted().collect(Collectors.toList()).forEach(元素 -> 操作(元素));
replace the above lambda with a method reference.
用方法引用替换上面的 lambda。
list.stream().sorted().collect(Collectors.toList()).forEach(this::operate);
list.stream().sorted().collect(Collectors.toList()).forEach(this::operate);