Другое решение может быть следующим:
Вот как вы его используете:
final Opt<String> opt = Opt.of("I'm a cool text");
opt.ifPresent()
.apply(s -> System.out.printf("Text is: %s\n", s))
.elseApply(() -> System.out.println("no text available"));
Или, если вы в случае противоположного варианта использования верны:
final Opt<String> opt = Opt.of("This is the text");
opt.ifNotPresent()
.apply(() -> System.out.println("Not present"))
.elseApply(t -> /*do something here*/);
Это ингредиенты:
- Немного измененный интерфейс функции, только для метода elseApply
- Дополнительное улучшение
- Немного карринга :-)
"Косметически" улучшенный интерфейс функций.
@FunctionalInterface
public interface Fkt<T, R> extends Function<T, R> {
default R elseApply(final T t) {
return this.apply(t);
}
}
И необязательный класс-оболочка для улучшения:
public class Opt<T> {
private final Optional<T> optional;
private Opt(final Optional<T> theOptional) {
this.optional = theOptional;
}
public static <T> Opt<T> of(final T value) {
return new Opt<>(Optional.of(value));
}
public static <T> Opt<T> of(final Optional<T> optional) {
return new Opt<>(optional);
}
public static <T> Opt<T> ofNullable(final T value) {
return new Opt<>(Optional.ofNullable(value));
}
public static <T> Opt<T> empty() {
return new Opt<>(Optional.empty());
}
private final BiFunction<Consumer<T>, Runnable, Void> ifPresent = (present, notPresent) -> {
if (this.optional.isPresent()) {
present.accept(this.optional.get());
} else {
notPresent.run();
}
return null;
};
private final BiFunction<Runnable, Consumer<T>, Void> ifNotPresent = (notPresent, present) -> {
if (!this.optional.isPresent()) {
notPresent.run();
} else {
present.accept(this.optional.get());
}
return null;
};
public Fkt<Consumer<T>, Fkt<Runnable, Void>> ifPresent() {
return Opt.curry(this.ifPresent);
}
public Fkt<Runnable, Fkt<Consumer<T>, Void>> ifNotPresent() {
return Opt.curry(this.ifNotPresent);
}
private static <X, Y, Z> Fkt<X, Fkt<Y, Z>> curry(final BiFunction<X, Y, Z> function) {
return (final X x) -> (final Y y) -> function.apply(x, y);
}
}
Это должно помочь и может послужить базовым шаблоном для работы с такими требованиями.
Основная идея здесь следующая. В мире программирования нефункционального стиля вы, вероятно, реализуете метод, принимающий два параметра, где первый - это своего рода исполняемый код, который должен выполняться, если значение доступно, а другой параметр - это исполняемый код, который должен быть запущен в случае значение недоступно. Для лучшей читаемости вы можете использовать curring, чтобы разделить функцию двух параметров на две функции по одному параметру каждая. Это то, что я в основном делал здесь.
Подсказка: Opt также предоставляет другой вариант использования, когда вы хотите выполнить фрагмент кода на случай, если значение недоступно. Это можно сделать также через Optional.filter.stuff, но я нашел его более читаемым.
Надеюсь, это поможет!
Хорошее программирование :-)
person
Alessandro Giusa
schedule
09.07.2016
orElse
для чего-то другого. - person Sotirios Delimanolis   schedule 21.05.2014return null;
наreturn o;
(оба). Однако у меня есть сильное чувство, что вы работаете не в том месте. Вы должны работать на сайте, который выпустил этоOptional
. В этом месте должен быть способ выполнить желаемую операцию без промежуточногоOptional
. - person Holger   schedule 22.05.2014ifPresent
противоречит этому. Все остальные методы относятся к значению, а не к действиям. - person AlikElzin-kilaka   schedule 20.07.2017map
, даже менее функциональный, чем версияifPresent
. В функциональном программировании функции не должны вызывать никаких побочных эффектов, таких как печать и изменение других значений. Они могут только делать расчеты. Я избегаюmap
каждый раз, когда пытаюсь вызвать побочные эффекты. Когда вы видите вызовmap
, естественно предположить, что побочных эффектов не будет, только преобразование значения из-за его функционального фона. Использование его так, как следует из названия, - гораздо более семантический способ программирования. - person Addison   schedule 15.10.2018map
является ленивой операцией, что означает, что на самом деле она не будет вызывать переданный вами блок, пока вы не попытаетесь использовать или проверить значение необязательного . Поэтому, в зависимости от языка, такой оператор может никогда не быть выполнен и в результате будет оптимизирован. Это может не относиться к Java, но это важно знать. - person Addison   schedule 15.10.2018ifPresent(...)
в цепочку сorElse(...)
илиotherwise(...)
. - person Josh M.   schedule 15.08.2019