Необязательная функция <String>map возвращает ноль - PullRequest
0 голосов
/ 31 августа 2018

Может кто-нибудь помочь мне с приведенным ниже фрагментом кода? Я хотел бы эквивалент с использованием Optional функций.

public String getMyRequiredValue(Optional<String> value) {
    if(value.isPresent()) {
        Optional<String> optionVal = getAnotherValue(value.get());
        if(optionVal.isPresent()) {
            return optionVal.get();
        } else {
            return null;
        }
    } else {
        return "Random";
    }
}

public Optional<String> getAnotherValue(String value) { ... }

Просто заметка, я пробовал это, но это не работает

return value.map(lang -> getAnotherValue(lang).orElse(null)).orElse("Random");

То, что не работает, - когда значение присутствует и getAnotherValue возвращает Optional.empty() Я хочу, чтобы исходная функция возвращала null. Сейчас возвращается "Random".

Я предполагаю, что метод map возвращает null, его заменяют на "Random".

Обратите внимание, что оригинальный код был написан кем-то другим. Поскольку у него много зависимостей, я не могу изменить параметры ввода / вывода. (

1 Ответ

0 голосов
/ 31 августа 2018

Решение, изначально предложенное @ Andreas в комментариях:

public String getMyRequiredValue(Optional<String> value) {
    return value.isPresent() ? getAnotherValue(value.get()).orElse(null) : "Random";
}

Решение, которое я придумал первым. Это нарушает правило, которое предполагает, что мы всегда должны проверять isPresent() перед вызовом get(), и вводит обработку исключений. Так что лучше придерживаться первой идеи.

public String getMyRequiredValue2(Optional<String> value) {
    try {
        return getAnotherValue(value.get()).orElse(null);
    } catch (NoSuchElementException e) {
        return "Random";
    }
}

Я видел, как вы пытались использовать map и flatMap. Если они приводят к Optional.empty(), неясно, откуда взялась null: это может быть value или getAnotherValue(value.get()).

Мы можем отследить это, сохранив значение из value.get() в Holder<String>:

public String getMyRequiredValue3(Optional<String> value) {
    final Holder<String> holder = new Holder<>();
    return value.flatMap(i -> getAnotherValue(holder.value = i))
                .orElse(holder.value == null ? "Random" : null);
}

Опять же, первый подход все еще превосходит это.


РЕДАКТИРОВАТЬ: Как указано @ Holder , нам не нужно Holder из предыдущего примера. Вместо этого мы можем проверить value.isPresent():

public String getMyRequiredValue4(Optional<String> value) {
    return value.flatMap(this::getAnotherValue) 
                .orElse(value.isPresent() ? null : "Random");
}
...