【问题标题】:Sonar : Replace this lambda with a method reference. When should "stream()" be used? [duplicate]Sonar:用方法引用替换这个 lambda。什么时候应该使用“stream()”? [复制]
【发布时间】:2021-06-08 08:07:05
【问题描述】:

我想知道这两个三段代码有什么区别:

underlyingConnectors.values().stream().forEach(connector -> connector.start());

underlyingConnectors.values().forEach(connector -> connector.start());

underlyingConnectors.values().forEach(Connector::start);

第二行编译正常,但我的 Ecplipse IDE 报错“Sonar : Replace this lambda with a method reference”。

如何选择要使用的合适代码?是否每个都有特定的用例?

【问题讨论】:

标签: java sonarqube


【解决方案1】:

这两行都是正确的。这只是声纳棉绒的警告。方法引用是 lambda 的一种简单形式,以防您只返回一个方法。

【讨论】:

    【解决方案2】:

    第一行包含对stream() 的不必要调用,后两行是见仁见智。如果你想写最短和最简洁的代码,你会使用最后一个。它们都以相同的方式工作,主要是关于风格。

    stream() 是不必要的,因为 values() 返回一个 Collection,它扩展了 Iterable,而 Iterable 已经有 forEach(Consumer<? super T> action)

    【讨论】:

      【解决方案3】:

      如果您只是通过.forEach() 对每个元素执行一项操作,则可以省略.stream()。调用.stream() 是多余的。

      underlyingConnectors.values().stream().forEach(connector -> connector.start());
      underlyingConnectors.values().forEach(connector -> connector.start());
      

      第 2 行是正确的。

      如果您只是对每个条目应用一个操作,那么只需使用方法引用,无需编写 lambda。这基本上是一种速记。

      underlyingConnectors.values().forEach(connector -> connector.start());
      underlyingConnectors.values().forEach(Connector::start);
      

      第 2 行是正确的。

      【讨论】:

      • @Michael 啊我的坏
      【解决方案4】:

      第二个只是第一个的简写符号,第三个是第二个的简写符号。一个经验法则是,如果一个方法没有像第二个这样的参数,您可以简单地用像第三个这样的符号替换它。

      更一般地,如果 lambda 表达式右侧 (RHS) 的表达式是 lambda 表达式左侧 (LHS) 的方法调用,不需要额外的参数,或者是仅将表达式的左侧作为参数,然后可以将 lambda-expression 替换为方法引用 - 只要 RHS 采用两个参数,它就不像 Java 不支持在时刻作为一种语言功能,但可以用包装器代替:

      package com.example;
      
      import java.util.Arrays;
      import java.util.List;
      import java.util.function.Consumer;
      
      public class Application {
      
        private static final String LINEBREAK = System.lineSeparator();
      
        public static void main(String[] args) {
          final List<String> strings = Arrays.asList("Hello", "World", "!");
      
          strings.forEach(string -> System.out.print(string + LINEBREAK)); // 1
      
          strings.forEach(string -> Application.printWithLineBreakParameter(LINEBREAK).accept(string)); // 2
      
          strings.forEach(Application.printWithLineBreakParameter(LINEBREAK)); // 3
        }
      
        private static Consumer<String> printWithLineBreakParameter(final String lineBreak) {
          return (string) -> System.out.print(string + lineBreak);
        }
      }
      

      在这里,所有三个调用都是相等的,但是 2 可以替换为 3,使其看起来比 1 更整洁。

      【讨论】:

        猜你喜欢
        • 2019-05-11
        • 1970-01-01
        • 2018-12-26
        • 1970-01-01
        • 2019-12-26
        • 2012-03-23
        • 2014-05-19
        • 1970-01-01
        相关资源
        最近更新 更多