Назначение локальных переменных внутри лямбда-выражения - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь изучить и понять использование лямбда-выражений в Java.

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

private boolean isNullOrEmpty(Optional<String> value) {
  boolean result;
  value.ifPresent(v -> result = isEmptyOrWhitespace(v));

  return result;
} 

isEmptyOrWhitespace - это простая функция, которую я определил в другом месте, чтобы проверить, является ли строка нулевой или имеет только пробел:

private boolean isEmptyOrWhitespace(String value) {
    return value == null || value.trim().isEmpty();

Проблема в том, что я не могу скомпилировать это, потому что компилятор говорит

variable used in lambda should be final or effectively final

Для переменной result. Я видел Java: назначьте переменную в lambda с похожей проблемой, но там была проблема с String, и было решено предварительно установить ее в null.

Я чувствую, что я рядом. Как я могу это исправить?

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Вариант А - Перепишите код:

private boolean isNullOrEmpty(Optional<String> value) {
    return value.map(MyClass::isEmptyOrWhitespace).orElse(false);
}

Вариант B - Обойти «эффективно окончательное» ограничение:

private boolean isNullOrEmpty(Optional<String> value) {
    boolean[] result = {false};
    value.ifPresent(v -> result[0] = isEmptyOrWhitespace(v));
    return result[0];
} 

Ссылка на массив является окончательной, ее содержимое не обязательно должно быть.

0 голосов
/ 28 июня 2018

Вы можете использовать filter с isPresent:

value.filter(x-> isEmptyOrWhitespace(x)).isPresent()
0 голосов
/ 28 июня 2018

Проблема в том, что result не является эффективно окончательным , так как для него имеется более одного назначения.

Вы можете использовать Optional.map

private boolean isNullOrEmpty(Optional<String> value) {
  return value.map(v -> isEmptyOrWhitespace(v)) //Or can use a Method reference as mentioned by Bohemian@
        .orElse(false);
} 
...