此代码示例
Collection<Number> values = transform(
getValuatedObjects(),
input -> getValueProvider().apply(input).getValue());
违反了sonarqube rule:
尽可能用方法引用替换lambdas
是声纳虫吗? 或者我真的可以使用方法参考吗?
答案 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**);