[解決済み】Java 8のOptional.ifPresentとif-not-Presentの機能的なスタイル?
2022-04-14 14:38:39
質問
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
を作成し、データベースに保存する。
2つのラムダで、私は
null
.
しかし
opt
が存在すると、両方のラムダが実行されます。
obj
が更新され、新しいオブジェクトがデータベースに保存されます。これは
return null
を最初のラムダに追加しています。そして
orElseGet()
が実行され続けます。
解決方法は?
私にとっては、@Dane Whiteの回答はOKです。
Runnable
しかし、代替案が見つからなかった。
私がもっと気に入った別の実装を紹介します。
public class OptionalConsumer<T> {
private Optional<T> optional;
private OptionalConsumer(Optional<T> optional) {
this.optional = optional;
}
public static <T> OptionalConsumer<T> of(Optional<T> optional) {
return new OptionalConsumer<>(optional);
}
public OptionalConsumer<T> ifPresent(Consumer<T> c) {
optional.ifPresent(c);
return this;
}
public OptionalConsumer<T> ifNotPresent(Runnable r) {
if (!optional.isPresent()) {
r.run();
}
return this;
}
}
次に
Optional<Any> o = Optional.of(...);
OptionalConsumer.of(o).ifPresent(s -> System.out.println("isPresent " + s))
.ifNotPresent(() -> System.out.println("! isPresent"));
アップデート1
上記の解決策は、従来の開発方法で、値があり、それを処理したい場合ですが、機能を定義して実行したい場合はどうしたらよいでしょうか?
public class OptionalConsumer<T> implements Consumer<Optional<T>> {
private final Consumer<T> c;
private final Runnable r;
public OptionalConsumer(Consumer<T> c, Runnable r) {
super();
this.c = c;
this.r = r;
}
public static <T> OptionalConsumer<T> of(Consumer<T> c, Runnable r) {
return new OptionalConsumer(c, r);
}
@Override
public void accept(Optional<T> t) {
if (t.isPresent()) {
c.accept(t.get());
}
else {
r.run();
}
}
とすると、次のように使える。
Consumer<Optional<Integer>> c = OptionalConsumer.of(
System.out::println,
() -> System.out.println("Not fit")
);
IntStream.range(0, 100)
.boxed()
.map(i -> Optional.of(i)
.filter(j -> j % 2 == 0))
.forEach(c);
この新しいコードでは、3つのことを行っています。
- オブジェクトが存在する前に、簡単に機能を定義することができます。
- 各Optionalのオブジェクト参照を作成せず、1つだけなので、メモリが少なく、GCも少なくなります。
- 他のコンポーネントでより良く使用できるようにコンシューマを実装しています。
ちなみに、この名前はよりわかりやすく、Consumer<Optional<?>>.と呼ばれています。
関連
-
[解決済み] Maven: assembly-pluginが全く実行されない
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] Java で、あるコンストラクタを別のコンストラクタから呼び出すにはどうすればよいですか?
-
[解決済み] Javaで配列を宣言し、初期化する方法は?
-
[解決済み] Java内部クラスと静的ネストされたクラス
-
[解決済み] (関数型)リアクティブプログラミングとは?
-
[解決済み] なぜJava 8のOptionalは引数で使ってはいけないのか
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] tempとは何ですか、またjavaにおけるtempの用途は何ですか?
-
[解決済み] maven. -source 1.5ではラムダ式がサポートされていません。
-
[解決済み] HashMapのtoString関数はなぜ異なる順序で自分自身を印刷するのですか?
-
[解決済み] ストリングビルダー.イコール Java
-
[解決済み] JOGLまたはLWJGLの既成のプロジェクト
-
[解決済み] JAVA_OPTIONS、JAVA_TOOL_OPTIONS、JAVA_OPTSの違いについて
-
[解決済み] Javaにおけるシンボリック参照
-
[解決済み] 文字列が一意な文字であるかどうかを判定する
-
[解決済み] Javaでdoubleをfloatに変換する
-
[解決済み] JavaにおけるOptional orElse Optional