声纳:用方法参考替换此lambda

时间:2014-09-01 13:26:08

标签: lambda java-8 sonarqube

此代码示例

Collection<Number> values = transform(
        getValuatedObjects(),
        input -> getValueProvider().apply(input).getValue());

违反了sonarqube rule

  

尽可能用方法引用替换lambdas

是声纳虫吗? 或者我真的可以使用方法参考吗?

3 个答案:

答案 0 :(得分:27)

您无法在不更改语义的情况下使用方法引用替换lambda input -> getValueProvider().apply(input).getValue()

方法引用替换单个方法调用,因此它不能简单地替换由多个方法调用组成的lambda表达式。

input -> getValueProvider().apply(input)形式的lambda表达式可以由getValueProvider()::apply替换,当且仅当getValueProvider()的评估时间无关紧要,因为lambda形式调用该方法在每个lambda body评估时,对于方法引用,它只被调用一次并捕获结果。

这类似于x -> System.out.println(x)System.out::println之间的差异,其中读取字段System.out的内容在不同时间发生但通常无关紧要。但你应该意识到差异。

在您的示例中,调用第三个方法getValue()。使用方法引用表达它的唯一方法是需要像Function这样的函数接口,它具有andThen和/或compose等方法。但是,Java 8的工作方式,需要将第一个方法引用转换为目标接口来调用组合方法,这种方法现在更容易读取你现在拥有的lambda表达式:((Function<X,Y>)getValueProvider()::apply).andThen(Y::getValue) where {{ 1}}是类型,Y返回。

请注意,该规则说“在可能的情况下用方法引用替换lambda”“这给你提供了空间来说,”好吧,这里不可能“,但是,我不知道你有多少可以称之为“规则”然后......

答案 1 :(得分:3)

list.stream()。sorted()。collect(Collectors.toList())。forEach(element-> 操作(元素));

将上述lambda替换为方法参考。

list.stream()。sorted()。collect(Collectors.toList())。forEach(this :: operate);

答案 2 :(得分:0)

如果您使用Java 8进行编码,则可以使用方法引用代替lambda表达式以使代码可读

List<Integer> list = Arrays.asList(1,2,3,4,5);

将此lambda替换为方法参考

strList.stream().sorted().collect(Collectors.toList()).forEach(**s -> System.out.println(s)**);

替换

strList.stream().sorted().collect(Collectors.toList()).forEach(**System.out::println**);