IntelliJ - ссылка на метод может изменить семантику - PullRequest
4 голосов
/ 18 апреля 2020

У меня есть следующий код:

return userService.getAll()
    .stream()
    .map(User::getRoleName)
    .map(roleName -> roleService.findRoleByName(roleName))
    .collect(Collectors.toSet());

Кажется, что roleName -> roleService.findRoleByName(roleName) может быть заменено ссылкой на метод (а именно Ссылка на метод экземпляра конкретного объекта ), однако IntelliJ IDEA предупреждает, что это может изменить семантику:

screenshot

Как это может изменить семантику? Изменит ли это семантику?

1 Ответ

1 голос
/ 18 апреля 2020

Если вы не следуете правилам чистого функционального программирования, при преобразовании лямбды в ссылку на метод может произойти изменение семантики.

Разница в том, что ссылка на метод будет разрешена при построении потока. Но в лямбда-выражении код для получения метода может оцениваться при каждом выполнении лямбда-выражения.

Вот краткий автономный пример для демонстрации:

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();
  }
}

Hwo, чтобы избежать этой проблемы: не используйте побочные эффекты при работе с потоками. Не используйте peek для обработки! Этот метод существует главным образом для поддержки отладки (посмотрите на javado c).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...