Заменить if в optional java

Задание сгенерировать юзернейм с 1 буквы имени, фамилии и даты рождения, если даты рождения нет, использовать сегодняшний год и это все используя optional.

Код который работает, но не использует все привилегии optional + в return должно быть userName, а не optional:

public static Optional<String> generateUsername(Person p) {
    String userName;
    if (p.getBirthDate() == null) {
        userName =
                p.getFirstName().substring(0, 1).toLowerCase() + p.getLastName().toLowerCase() + Year.now();
    } else {
        userName =
                p.getFirstName().substring(0, 1).toLowerCase() + p.getLastName().toLowerCase() + p.getBirthDate().getYear();
    }
    return Optional.of(userName);

Не до конца понимаю как здесь работает consumer и как бы его правильно тут применить с лямбдой. Спасибо.


Ответы (1 шт):

Автор решения: Дмитрий

Мне кажется, что вы не понимаете суть Optional. Это не альтернатива условным операторам, это попытка решить проблему NullPointerException. Основная идея в том, что Optional является контейнером, который может хранить как объект, так и быть пустым (альтернатива null). При этом сам объект Optional никогда не равен null, следовательно, вызывать у него методы безопасно. При правильном применении все методы будут возвращать либо объекты определенного типа (никогда не равные null), либо Optional (вместо null), типизированный нужным типом. И в этом случае все методы, возвращающие реальные объекты (не Optional) никогда(!!!) не должны возвращать null, а везде, где возможен null возвращается Optional, следовательно, разработчик, работающий с такими методами, никогда не получит NullPointerException, потому как все null запакованы в Optional, посему это видно сразу при вызове метода, а остальные возвращаемые значения никогда не бывают null. Ну и, разумеется, Optional предоставляет нам методы работы с вложенными данными, учитывая, что там может быть null, позволяющие писать более лаконичный код без прямой проверки на null с помощью условного оператора.

Исходя из сказанного, я вижу только один способ применения Optional в описанной задаче:

class Person{
    
    private LocalDate birthDate;
    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }
    
    public Optional<LocalDate> getBirthDate() {
        return birthDate==null ? Optional.empty() : Optional.of(birthDate);
    }
    
    public static String generateUsername(Person p) {        
        return p.getBirthDate()
                .map(birthDate -> p.getFirstName().substring(0, 1).toLowerCase() + p.getLastName().toLowerCase() + birthDate.getYear())
                .orElseGet(() -> p.getFirstName().substring(0, 1).toLowerCase() + p.getLastName().toLowerCase() + LocalDate.now().getYear());
    }
    
}
→ Ссылка