Как использовать Java по желанию для элегантной замены тернарных операторов - PullRequest
0 голосов
/ 09 ноября 2018

Супер простой вопрос:

Вот мой простой Java-код с использованием традиционного троичного оператора ?

public DateTime getCreatedAt() {
    return !recordA.isPresent() ? recordB.get().getCreatedAt() : recordA.get().getCreatedAt();
}

Моя лучшая ставка следующая:

public DateTime getCreatedAt() {
    return recordA.map(
        record -> record.getCreatedAt())
        .orElse(recordB.get().getCreatedAt());
  }

Это может скомпилироваться, но похоже, что он не ведет себя правильно. Он всегда выполняет обе ветви, т.е. когда recordA isPresent (), он все еще выполняет recordB.get().getCreatedAt(), что бросает меня

java.util.NoSuchElementException: No value present

Любой ценится! По сути, я бы хотел заменить традиционный троичный вариант более продвинутыми опциональными / лямда-функциями. СПАСИБО!

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Вы ищете .orElseGet(() -> recordB.get().getCreatedAt());, и причину этого можно найти в этом посте -> Разница между Optional.orElse() и Optional.orElseGet()

Некоторым людям это может показаться немного субъективным, но лично я бы сказал, что по умолчанию имеет смысл использовать orElseGet() вместо orElse каждый раз, за ​​исключением случая, когда объект по умолчанию уже построен как это предотвратит многие неожиданные проблемы (учитывая, что вы не читали различий между документами orElse и orElseGet), как те, с которыми вы столкнулись сейчас.

читать больше от Java Необязательно - orElse () против orElseGet ()

0 голосов
/ 09 ноября 2018

Мой вопрос о том, что recordB является Optional, остался без ответа, но если это Optional, то вы не можете просто безопасно вызвать его метод get, вам нужно проверить, является ли он пустым или нет. Здесь безопасный вызов, чтобы получить запись или ноль, если оба recordA и recordB пусты Otional s.

        recordA
            .map(Record::getCreatedAt)
            .orElseGet( () -> recordB.map(Record::getCreatedAt).orElse(null) );
0 голосов
/ 09 ноября 2018

Чтобы избежать энергичной оценки else-веток, используйте orElseGet, который принимает экземпляр функционального интерфейса Supplier:

return recordA.map(
    record -> record.getCreatedAt())
    .orElseGet(() -> recordB.get().getCreatedAt());
...