Ваша главная ошибка в том, что вы все еще мыслите более процедурно. Это не критика вас как личности, это просто наблюдение. Мышление в более функциональных терминах приходит со временем и практикой, и поэтому методы isPresent и выглядят как наиболее очевидные правильные вещи для вас. Ваша второстепенная незначительная ошибка - создание вашего Optional внутри вашего метода. Необязательный предназначен для того, чтобы помочь документировать, что что-то может или не может возвращать значение. Вы можете ничего не получить.
Это привело к тому, что вы пишете совершенно разборчивый код, который кажется вполне разумным, но вас соблазнили мерзкие двойники-соблазнители, которые получают и представляют.
Конечно, быстро возникает вопрос: «Почему они присутствуют и даже там?»
Многие люди здесь упускают из виду то, что isPresent () состоит в том, что это не то, что сделано для нового кода, написанного полностью занятыми людьми с тем, насколько чертовски полезны лямбды и кому нравится функциональность.
Это, однако, дает нам несколько (два) хороших, великих, гламурных (?) Преимуществ:
- Это облегчает переход унаследованного кода на использование новых функций.
- Это облегчает изучение кривых Факультативного.
Первый довольно прост.
Представьте, что у вас есть API, который выглядел так:
public interface SnickersCounter {
/**
* Provides a proper count of how many snickers have been consumed in total.
*/
public SnickersCount howManySnickersHaveBeenEaten();
/**
* returns the last snickers eaten.<br>
* If no snickers have been eaten null is returned for contrived reasons.
*/
public Snickers lastConsumedSnickers();
}
И у вас был унаследованный класс, использующий это как таковой (заполните пробелы):
Snickers lastSnickers = snickersCounter.lastConsumedSnickers();
if(null == lastSnickers) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers);
}
Придуманный пример, чтобы быть уверенным. Но потерпите меня здесь.
Java 8 уже запущена, и мы карабкаемся, чтобы попасть на борт. Таким образом, мы хотим заменить наш старый интерфейс чем-то, что возвращает Optional. Почему? Потому что, как кто-то другой уже любезно упомянул:
это снимает догадки о том, может ли что-то быть нулевым.
Это уже было указано другими. Но сейчас у нас проблема. Представьте, что у нас есть (извините, когда я нажимаю alt + F7 невинного метода) 46 мест, где этот метод вызывается в хорошо проверенном унаследованном коде, который отлично работает в противном случае. Теперь вы должны обновить все это.
Это где настоящее сияет.
Потому что сейчас: Snickers lastSnickers = snickersCounter.lastConsumedSnickers (); if (null == lastSnickers) {throw new NoSuchSnickersException (); } else {consumer.giveDiabetes (lastSnickers); }
будет выглядеть так:
Optional<Snickers> lastSnickers = snickersCounter.lastConsumedSnickers();
if(!lastSnickers.isPresent()) {
throw new NoSuchSnickersException();
}
else {
consumer.giveDiabetes(lastSnickers.get());
}
И это простое изменение, которое вы можете дать новому юниору: он может сделать что-то полезное, и он сможет одновременно исследовать кодовую базу. беспроигрышная. В конце концов, что-то похожее на этот шаблон довольно широко распространено. И теперь вам не нужно переписывать код, чтобы использовать лямбды или что-то еще. (В этом конкретном случае это было бы тривиально, но я оставляю продуманные примеры, где это было бы сложно в качестве упражнения для читателя.)
Обратите внимание, что это означает, что то, как вы это сделали, по сути является способом работы с устаревшим кодом без дорогостоящих переписываний. Так что насчет нового кода?
Ну, в вашем случае, когда вы просто хотите что-то напечатать, вы просто сделаете:
. SnickersCounter.lastConsumedSnickers () ifPresent (System.out :: Println);
Что довольно просто и совершенно понятно. Точка, которая медленно поднимается к поверхности, состоит в том, что существуют варианты использования для get () и isPresent (). Они предназначены для того, чтобы позволить вам механически модифицировать существующий код, чтобы использовать новые типы, не слишком задумываясь об этом. То, что вы делаете, поэтому вводится в заблуждение следующими способами:
- Вы вызываете метод, который может вернуть ноль. Правильная идея состоит в том, что метод возвращает ноль.
- Вы используете устаревшие методы bandaid, чтобы справиться с этим необязательным, вместо того, чтобы использовать новые вкусные методы, которые содержат причудливость лямбды.
Если вы хотите использовать Optional в качестве простой проверки нулевой безопасности, вам нужно просто выполнить следующее:
new Optional.ofNullable(employeeServive.getEmployee())
.map(Employee::getId)
.ifPresent(System.out::println);
Конечно, красивая версия выглядит так:
employeeService.getEmployee()
.map(Employee::getId)
.ifPresent(System.out::println);
Кстати, хотя это ни в коем случае не требуется, я рекомендую использовать новую строку для каждой операции, чтобы ее было легче читать. Легко читать и понимать бьет краткость в любой день недели.
Это, конечно, очень простой пример, в котором легко понять все, что мы пытаемся сделать. Это не всегда так просто в реальной жизни. Но обратите внимание, что в этом примере мы выражаем наши намерения. Мы хотим ПОЛУЧИТЬ сотрудника, ПОЛУЧИТЬ его удостоверение личности и, если возможно, распечатать его. Это вторая большая победа с Факультативным. Это позволяет нам создавать более понятный код. Я также думаю, что создание таких вещей, как создание метода, который делает кучу вещей, чтобы вы могли передать их на карту, в общем, хорошая идея.