リストを返すメソッドにオプションを使用したい
関数が
public Output getListOfSomething() {
// In some cases there is nothing to return and hence it makes sense to have return
// type as Optional here
}
したがって、関数は次のようになります。
public Optional<List<String>> getListOfSomething() {
// return something only when there is some valid list
}
リストが存在する場合、次のように何かをしたい:
Optional<List<String>> listOfSomething = getListOfSomething();
int size = 0;
listOfSomething.ifPresent(size = listOfSomething.get().size());
私はオプションを初めて使用し、オプションに関する記事を読んでいますが、これは機能するはずですが、私のIDEで構文エラーが発生しています:
メソッドifPresentは引数に適用されません(void)。
Java 8のラムダにもっと精通しているかもしれない開発者から助けを得たいと思いました。
ここでセマンティクスについて考えることが重要です。
メソッドは、リスト、または「リストなし」を返す可能性があります。
リストを返す場合、空のリストを返す可能性があります。
「空のリストとリストなしを区別する意味的な理由はありますか」と尋ねるべきです。時々、違いを生む適切な設計上の理由がありますが、それはまれです。 EmptyとNullはあなたのケースで異なると判断する前に、よく考えてください。リストなしを避ける理由の一部は、クライアントコードが考慮しなければならない「特別なケース」を減らすことです。たとえば、返されるすべてのアイテムに対して何かを行う必要があるが、nullを返すこともできる場合、for eachループに入る前に、nullの特別なチェックを行う必要があります。リストが空の場合、for eachは何もしません。
問題のあるドメインで「リストなし」が「空のリスト」と異なる場合、クライアントコードがこれらの条件を区別し、適切に処理するのに役立つラッパークラスを返すと便利な場合があります。 Optional
はそのような汎用クラスの1つですが、ドメインはより具体的なものを要求する場合があります(Optionalの機能を模倣していても、より良いセマンティック定義を持っている場合があります)。
真の機能プログラミングの方法は次のとおりです。
size = listOfSomething.map(List::size).orElse(0);
ただし、List
の代わりに空のOptional
を返す方がはるかに良いでしょう。
ifPresentを使用するには、 Consumer インターフェイスが必要です。次のことができます。
Optional<List<String>> listOfSomething = getListOfSomething();
Integer[] size = {0};
listOfSomething.ifPresent(list -> size[0]=list.size())
しかし、 Tagir Valeevが述べたように 行う方が良いでしょう:
size = listOfSomething.map(List::size).orElse(0);
また、空のListまたはStreamを返すことをお勧めします。