Java 8.のOptional
APIのifPresent()
メソッドを理解しようとしています。
私は簡単なロジックを持っています:
Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));
ただし、これによりコンパイルエラーが発生します。
ifPresent(Java.util.functionError:(186, 74) Java: 'void' type not allowed here)
もちろん、私はこのようなことをすることができます:
if(user.isPresent())
{
doSomethingWithUser(user.get());
}
しかし、これは混乱したnull
チェックとまったく同じです。
コードをこれに変更すると:
user.ifPresent(new Consumer<User>() {
@Override public void accept(User user) {
doSomethingWithUser(user.get());
}
});
コードが汚れてきており、古いnull
チェックに戻ることを考えさせられます。
何か案は?
Optional<User>.ifPresent()
は、Consumer<? super User>
を引数として取ります。型がvoidである式を渡します。そのためコンパイルできません。
Consumerは、ラムダ式として実装されることを目的としています。
Optional<User> user = ...
user.ifPresent(theUser -> doSomethingWithUser(theUser));
または、メソッドリファレンスを使用してさらに簡単に:
Optional<User> user = ...
user.ifPresent(this::doSomethingWithUser);
これは基本的に同じです
Optional<User> user = ...
user.ifPresent(new Consumer<User>() {
@Override
public void accept(User theUser) {
doSomethingWithUser(theUser);
}
});
doSomethingWithUser()
メソッド呼び出しは、ユーザーが存在する場合にのみ実行されるという考え方です。コードはメソッド呼び出しを直接実行し、そのvoid結果をifPresent()
に渡そうとします。
@JBNizetの答えに加えて、ifPresent
の一般的な使用例は、.isPresent()
と.get()
を組み合わせることです。
古い方法:
Optional opt = getIntOptional();
if(opt.isPresent()) {
Integer value = opt.get();
// do something with value
}
新しい方法:
Optional opt = getIntOptional();
opt.ifPresent(value -> {
// do something with value
})
私にとって、これはより直感的です。
FlatMapを使用します。値が存在する場合、flatMapはその値のみを含むシーケンシャルStreamを返し、そうでない場合は空のStreamを返します。したがって、ifPresent()
を使用する必要はありません。例:
list.stream().map(data -> data.getSomeValue).map(this::getOptinalValue).flatMap(Optional::stream).collect(Collectors.toList());
次のようなメソッド参照を使用できます。
user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);
メソッドifPresent()
get Consumer
オブジェクトをパラメーターとして、および( JavaDoc )から:「値が存在する場合、その値で指定されたコンシューマーを呼び出します。」値は変数user
です。
または、このメソッドdoSomethingWithUser
がUser
クラスにあり、static
でない場合、次のようなメソッド参照を使用できます。
user.ifPresent(this::doSomethingWithUser);
単純にできるのに、なぜ複雑なコードを書くのですか?
実際、Optional
クラスを絶対に使用する場合、最も単純なコードは既に記述したものです...
if (user.isPresent())
{
doSomethingWithUser(user.get());
}
このコードには、次の利点があります。
OracleがJava 8にOptional
クラスを追加したからといって、このクラスをすべての状況で使用しなければならないわけではありません。