Проверьте значение null перед установкой переменной — без if-else

#java #java-8 #lombok

#java #java-8 #ломбок

Вопрос:

Я использую Lombok-Builder для создания своего api объекта Java из объекта entity

 RewardApi.builder()
                .rewardId(rewardEntity.getrewardId())
                .rewardTitle(rewardEntity.getrewardTitle())
                .rewardText(rewardEntity.getrewardText())
                .rewardFor(rewardEntity.getrewardFor())
                .rewardType(rewardEntity.getrewardType())
                .rewardFromDate(rewardEntity.getrewardFromDate().toZonedDateTime())
                .rewardToDate(rewardEntity.getrewardToDate().toZonedDateTime())
                .isDisplayOn(rewardEntity.getIsDisplayOn())
                .createdId(rewardEntity.getCreatedId())
                .updatedId(rewardEntity.getUpdatedId())
                .createdDate(rewardEntity.getCreatedDate().toZonedDateTime())
                .lastModifiedDate(rewardEntity.getLastModifiedDate().toZonedDateTime())
                .build();
 

Я получаю nullPointerException while я устанавливаю lastModifiedDate поле, потому entity что объект получает это поле как null и выполняется toZonedDateTime() поверх null

Как решить эту проблему без традиционного способа (как указано ниже) выполнения

if (null!=rewardEntity.getLastModifiedDate(){....}

Я хотел проверить null , пока я устанавливаю переменную с помощью builder-pattern , и не выполнять null проверку после создания объекта. Какие-либо способы?

Комментарии:

1. используйте троичный оператор

2. rewardEntity.getLastModifiedDate() != null? rewardEntity.getLastModifiedDate().toZonedDateTime() : null Я думаю

3. Есть ли у вас гибкость в использовании java 8, если да, то я бы предложил обернуть его в необязательный вариант примерно так Optional.ofNullable(rewardEntity.getLastModifiedDate()).map(z->z.toZonedDateTime()).orElse(null);

4. @foxt7ot Я бы сказал, да, учитывая теги.

5. @AndyTurner Да!! Полностью пропустил это:(

Ответ №1:

Всем детям нравятся Optional эти дни:

 Optional.ofNullable(rewardEntity.getLastModifiedDate())
    .map(r -> r.toZonedDateTime())
    .orElse(null) // or some other default value
 

Комментарии:

1. и OffsetDateTime::toZonedDateTime вместо r -> r.toZonedDateTime() , но я не понимаю, почему люди так настаивают на этих решениях с Optional

2. @Adrian provided getLastModifiedDate() возвращает a (подкласс) OffsetDateTime , да.

3. Это довольно круто, у меня был этот фрагмент кода в методе, и я вызвал его в том месте, где я устанавливаю lastModifiedDate

Ответ №2:

 rewardEntity.getLastModifiedDate() != null ? rewardEntity.getLastModifiedDate().toZonedDateTime() : null 
 

Это называется условным оператором, который является троичным оператором, поскольку он имеет три операнда.

Комментарии:

1. извините, я печатал со своего телефона

2. Я бы не рекомендовал сохранять нулевое значение, это может привести к NPE позже

3. но OP, скорее всего, уже делал это — как вы думаете, как работает этот конструктор?

Ответ №3:

у вас может быть общий служебный метод, который обрабатывает случаи null, например

 static <T, R> R transform(T obj, Function<T, R> function) {
    return obj != null ? function.apply(obj) : null;
}
 

и используйте его следующим образом

 .rewardToDate(transform(rewardEntity.getRewardToDate(), OffsetDateTime::toZonedDateTime))
 

На самом деле лучше «переопределить» методы lombok builder, потому что то, что у вас есть сейчас, больше похоже на заполнитель / DTO, а не на builder:

 @Builder
private static class RewardApi {
    //...
    private ZonedDateTime rewardToDate;

    public static class RewardApiBuilder {

        public RewardApiBuilder rewardToDate(OffsetDateTime offsetDateTime) {
            if(offsetDateTime != null) {
                this.rewardToDate = offsetDateTime.toZonedDateTime();
            }
            return this;
        }
    }
}