В Java 8 я хочу сделать что-то с Optional
объектом, если он присутствует, и сделать что-то другое, если его нет.
if (opt.isPresent()) {
System.out.println("found");
} else {
System.out.println("Not found");
}
Это не «функциональный стиль», хотя.
Optional
есть ifPresent()
метод, но я не могу связать orElse()
метод.
Таким образом, я не могу написать:
opt.ifPresent( x -> System.out.println("found " + x))
.orElse( System.out.println("NOT FOUND"));
В ответ на @assylias, я не думаю, что Optional.map()
работает в следующем случае:
opt.map( o -> {
System.out.println("while opt is present...");
o.setProperty(xxx);
dao.update(o);
return null;
}).orElseGet( () -> {
System.out.println("create new obj");
dao.save(new obj);
return null;
});
В этом случае, когда opt
присутствует, я обновляю его свойство и сохраняю в базу данных. Когда он недоступен, я создаю новый obj
и сохраняю в базу данных.
Обратите внимание на две лямбды, которые я должен вернуть null
.
Но когда opt
присутствует, обе лямбды будут выполнены. obj
будет обновлен, и новый объект будет сохранен в базе данных. Это из- return null
за первой лямбды. И orElseGet()
продолжим исполнять.
java
functional-programming
java-8
optional
smallufo
источник
источник
return null;
наreturn o;
(оба). Однако у меня есть сильное чувство, что вы работаете не в том месте. Вы должны работать на сайте, который произвел этоOptional
. В этом месте должен быть способ выполнить желаемую операцию без промежуточного звенаOptional
.ifPresent
противоречит этому. Все остальные методы относятся к значению, а не к действиям.Ответы:
Для меня ответ @Dane White в порядке, сначала мне не нравилось использовать Runnable, но я не мог найти альтернатив, здесь другая реализация, которую я предпочел больше
Затем :
Обновление 1:
вышеупомянутое решение для традиционного способа разработки, когда у вас есть значение и вы хотите его обработать, но что если я захочу определить функциональность и выполнение, тогда отметьте расширение ниже;
Тогда можно использовать как:
В этом новом коде у вас есть 3 вещи:
кстати, теперь его название более наглядно, это на самом деле Consumer>
источник
Если вы используете Java 9+, вы можете использовать
ifPresentOrElse()
метод:источник
Java 9 вводит
ifPresentOrElse, если значение присутствует, выполняет данное действие со значением, в противном случае выполняет данное пустое действие.
См. Отлично Дополнительный в Java 8 шпаргалке .
Он предоставляет все ответы для большинства случаев использования.
Краткое резюме ниже
ifPresent () - сделать что-нибудь, когда установлен Optional
filter () - отклонить (отфильтровать) определенные дополнительные значения.
map () - преобразовать значение, если оно присутствует
orElse () / orElseGet () - становится пустым Необязательно для значения по умолчанию T
orElseThrow () - лениво выбрасывать исключения на пустую опцию
источник
map
, но немного странно просить функциональное решение, чтобы вы могли вызвать DAO. Мне кажется, было бы больше смысла возвращать обновленный / новый объект из этогоmap.orElse
блока, а затем делать то, что вам нужно сделать с возвращенным объектом.map
сосредоточиться на самом потоке и не предназначен для «выполнения действий с другим объектом в зависимости от состояния этого элемента в потоке». Полезно знать, чтоifPresentOrElse
добавлено в Java 9.Альтернатива:
Я не думаю, что это улучшает читабельность, хотя.
Или, как предложил Марко, используйте троичный оператор:
источник
new Object();
в первую лямбду, но, честно говоря, это становится очень уродливо. Я бы придерживался if / else для вашего обновленного примера.map
простого возвратаOptional
для создания цепочки усложняет понимание кода, в то времяmap
как предполагается, что оно буквально отображается на что-то.Другое решение было бы использовать функции высшего порядка следующим образом
источник
value -> () -> syso
означает эта часть.String result = opt.map(value -> "withOptional").orElse("without optional");
Там нет отличный способ сделать это из коробки. Если вы хотите регулярно использовать более чистый синтаксис, вы можете создать вспомогательный класс, который поможет:
Затем вы можете использовать статический импорт в другом месте, чтобы получить синтаксис, близкий к тому, что вы ищете:
источник
Optional.ifPresentOrElse()
был добавлен в JDK 9.Если вы можете использовать только Java 8 или ниже:
1) если у вас пока нет
spring-data
лучшего способа это:Теперь я знаю, что это не так легко читается и даже трудно понять для кого-то, но лично выглядит хорошо для меня, и я не вижу другого хорошего беглого пути для этого случая.
2) если вам повезло и вы можете использовать
spring-data
лучший способ, это Optionals # ifPresentOrElse :Если вы можете использовать Java 9, вы обязательно должны пойти с:
источник
Описанное поведение может быть достигнуто с помощью Vavr (ранее известного как Javaslang), объектно-функциональной библиотеки для Java 8+, которая реализует большинство конструкций Scala (будучи Scala - более выразительным языком с более богатой системой типов, построенной на JVM). Это очень хорошая библиотека для добавления в ваши проекты Java для написания чистого функционального кода.
Vavr предоставляет
Option
монаду, которая предоставляет функции для работы с типом Option, такие как:fold
: отобразить значение опции в обоих случаях (определено / пусто)onEmpty
: позволяет выполнить,Runnable
когда опция пустаpeek
: позволяет использовать значение параметра (когда оно определено).Serializable
наоборот,Optional
это означает, что вы можете безопасно использовать его в качестве аргумента метода и члена экземпляра.Опция следует монадическим законам в отличие от опциональной псевдомонады Java и предоставляет более богатый API. И, конечно, вы можете сделать это из опционального Java (и наоборот):
Option.ofOptional(javaOptional)
–Vavr сфокусирован на совместимости.Переходя к примеру:
дальнейшее чтение
Нулевая ссылка, ошибка в миллиард долларов
NB. Это всего лишь небольшой пример того, что предлагает Vavr (сопоставление с образцом, потоки или ленивые оценочные списки, монадические типы, неизменяемые коллекции, ...).
источник
Другое решение может быть следующим:
Вот как вы используете это:
Или в случае, если вы в случае противоположного варианта использования верно:
Это ингредиенты:
«Косметически» расширенный интерфейс функций.
И необязательный класс-оболочка для улучшения:
Это должно сделать свое дело и может послужить основным шаблоном, как справиться с такими требованиями.
Основная идея здесь следующая. В мире программирования не функционального стиля вы, вероятно, реализовали бы метод, принимающий два параметра, где первый - это разновидность исполняемого кода, который должен выполняться при наличии значения, а другой параметр - исполняемый код, который должен выполняться в случае, если значение не доступно. Для лучшей читабельности вы можете использовать curring для разделения функции двух параметров на две функции по одному параметру в каждой. Это то, что я в основном сделал здесь.
Подсказка: Opt также предоставляет другой вариант использования, где вы хотите выполнить фрагмент кода на случай, если значение недоступно. Это можно сделать также через Optional.filter.stuff, но я нашел это гораздо более читабельным.
Надеюсь, это поможет!
Хорошее программирование :-)
источник
Если вы хотите сохранить значение:
источник
Предполагая, что у вас есть список и избегая
isPresent()
проблемы (связанной с дополнительными), вы можете использовать,.iterator().hasNext()
чтобы проверить, если нет.источник