Java IntelliJ-方法引用可能会更改语义

Java IntelliJ-方法引用可能会更改语义,java,intellij-idea,lambda,Java,Intellij Idea,Lambda,我有以下代码: 返回userService.getAll() .stream() .map(用户::getRoleName) .map(roleName->roleService.findRoleByName(roleName)) .collect(收集器.toSet()); 似乎roleName->roleService.findRoleByName(roleName)可以被方法引用(即对特定对象的实例方法的引用)替换,但是IntelliJ IDEA警告说,这可能会改变语义: 它如何改变语

我有以下代码:

返回userService.getAll()
.stream()
.map(用户::getRoleName)
.map(roleName->roleService.findRoleByName(roleName))
.collect(收集器.toSet());
似乎
roleName->roleService.findRoleByName(roleName)
可以被方法引用(即对特定对象的实例方法的引用)替换,但是IntelliJ IDEA警告说,这可能会改变语义:


它如何改变语义?它会改变语义吗?

如果您不遵循干净函数式编程的规则,那么当您将lambda转换为方法引用时,可能会改变语义

不同之处在于,方法引用将在构建流时解析。但是在lambda表达式中,可以在lambda的每次执行中计算用于获取方法的代码

下面是一个简短的独立示例,用于演示:

public class Test40 {
  public static void main(String[] args) {
    Function<Integer, Integer> f2 = n -> 2 * n;
    Function<Integer, Integer> f3 = n -> 3 * n;
    Function<Integer, Integer>[] funcArray = new Function[1];

    funcArray[0] = f2;
    Stream.of(1, 2, 3)
          .peek(n -> { if (n > 1 ) funcArray[0] = f3; })
          .map(funcArray[0]::apply)            // Method reference, '::apply' could be omitted
          .forEach(System.out::print);         // prints 246
    System.out.println();

    funcArray[0] = f2;
    Stream.of(1, 2, 3)
          .peek(n -> { if (n > 1 ) funcArray[0] = f3; })
          .map(n -> funcArray[0].apply(n))     // Lambda
          .forEach(System.out::print);         // prints 269
    System.out.println();
  }
}
公共类Test40{
公共静态void main(字符串[]args){
功能f2=n->2*n;
功能f3=n->3*n;
函数[]funcArray=新函数[1];
funcArray[0]=f2;
(1、2、3)流
.peek(n->{if(n>1)funcArray[0]=f3;})
.map(funcArray[0]::apply)//方法引用“::apply”可以省略
.forEach(System.out::print);//打印246
System.out.println();
funcArray[0]=f2;
(1、2、3)流
.peek(n->{if(n>1)funcArray[0]=f3;})
.map(n->funcArray[0]。应用(n))//Lambda
.forEach(System.out::print);//打印269
System.out.println();
}
}

如何避免此问题:处理流时不要使用副作用。不要使用
peek
进行处理!这种方法主要是为了支持调试(看看javadoc)。

使用该工具时IntelliJ会产生什么?“更改语义”似乎有点难以准确解释。我还要补充一点:除了sout或日志之外,不要使用forEach,因为这也是一种副作用,不推荐使用。是的,
forEach
也有副作用。大多数情况下都有更好的(功能性)方法,因此应避免使用
forEach
。我的本意并不是为了完成不该做的事。正如我的示例使用的
peek
,我想说:“不要在家里这样做”:-)