Несколько нулевых проверок с использованием Optional в Java 8 - PullRequest
2 голосов
/ 19 марта 2020

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

LocalDateTime beDate = someDate;
LocalDateTime aeDate = someDate;
LocalDateTime eDate;

if (beDate == null && aeDate == null) {
    eDate = null;
}
else if (beDate != null && aeDate == null) {
    eDate = beDate;
}
else if (beDate == null && aeDate != null) {
    eDate =  aeDate;
}
else if (beDate != null && aeDate != null && 
        (beDate.isEqual(aeDate) || beDate.isBefore(aeDate))) {
    eDate = beDate;
}
else {
    eDate = aeDate;
}

Ответы [ 4 ]

10 голосов
/ 19 марта 2020

Лог c здесь очень сложен для понимания. Вместо этого express ваше намерение более прямо:

private static final Comparator<ChronoLocalDateTime<?>> EARLIEST_PRESENT = 
    Comparator.nullsLast(Comparator.naturalOrder());

LocalDateTime eDate = BinaryOperator.minBy(EARLIEST_PRESENT).apply(beDate, aeDate);

(обратите внимание, что stati c импорт для элементов из Comparator и BinaryOperator сделает это еще яснее.)

7 голосов
/ 19 марта 2020

Ваши условия являются избыточными, учитывая, что результатом является только один из двух возможных результатов:

if (beDate == null && aeDate == null) {
    eDate = null;
}
else if (beDate != null && aeDate == null) {
    eDate = beDate;
}
...

Здесь eDate будет иметь то же содержимое, что и beDate в любом случае, будь то null или нет. Так что if(aeDate == null) eDate = beDate; было бы достаточно. Во всех других случаях вы присваиваете aeDate, с одним единственным исключением:

...
else if (beDate != null && aeDate != null && 
        (beDate.isEqual(aeDate) || beDate.isBefore(aeDate))) {
    eDate = beDate;
}
...

Мы можем упростить beDate.isEqual(aeDate) || beDate.isBefore(aeDate) до aeDate.isAfter(beDate).

Таким образом, весь оператор может быть записывается как:

LocalDateTime eDate
    = aeDate == null || (beDate != null && aeDate.isAfter(beDate))? beDate: aeDate;

Короткое замыкание || означает, что правая сторона оценивается только тогда, когда левая сторона равна false, поэтому, когда левая сторона равна aeDate == null, для правой стороны подразумевается, что aeDate != null и повторяться не нужно.

Таким образом, eDate получит значение beDate, когда aeDate равно null (первые два оператора if) или когда оба не null, а aeDate - после beDate (другой цитированный оператор if), и получают значение aeDate в противном случае.

Приоритет оператора делает скобки ненужными, но также допустимо сохранять их для ясности.

2 голосов
/ 19 марта 2020

Вы можете использовать ObjectUtils :: min из Apache Commons:

LocalDateTime eDate = ObjectUtils.min(aeDate, beDate);

Решение - один вкладыш и легко читается.

2 голосов
/ 19 марта 2020

Вы можете использовать Optional.ofNullable, но я не рекомендую это.

Завершение всего в Optional не облегчит чтение. Вы должны сделать проверку null, чтобы заменить obj == null на obj.isEmpty() (или obj.isEmpty() в java 8).

...