Sonar:用方法引用替换此 lambda

新手上路,请多包涵

此代码示例

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

违反了 Sonarqube 规则

Lambda 应替换为方法引用

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

原文由 gontard 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 474
2 个回答

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

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

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

这类似于 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) 其中 Y 是类型, apply(input) 返回。

请注意,规则说“ 尽可能 用方法引用替换 lambda”,这让您有余地说,“好吧,这里是不可能的”,但是,我不确定您可以在多大程度上称其为“规则”……

原文由 Holger 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

用方法引用替换上面的 lambda。

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

原文由 Akanksha gore 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题