別の解決策は次のとおりです:
これはあなたがそれを使う方法です:
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」メソッド専用の、少し変更されたFunctionインターフェース
- オプションの機能強化
- 少しカーリング:-)
「美容的に」強化された関数インターフェース。
@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);
}
}
これはうまくいくはずであり、そのような要件に対処する方法の基本的なテンプレートとして機能する可能性があります。
ここでの基本的な考え方は次のとおりです。非関数型のプログラミングの世界では、おそらく2つのパラメーターを取るメソッドを実装します。最初のパラメーターは、値が使用可能な場合に実行する必要がある実行可能コードの一種で、もう1つのパラメーターは、場合に実行する必要がある実行可能コードです。値は利用できません。読みやすくするために、curringを使用して、2つのパラメーターの関数を、それぞれ1つのパラメーターの2つの関数に分割できます。これは私が基本的にここでやったことです。
ヒント:Optは、値が利用できない場合に備えてコードの一部を実行する他のユースケースも提供します。これはOptional.filter.stuffでも行うことができますが、これははるかに読みやすくなっています。
お役に立てば幸いです。
良いプログラミング:-)