web-dev-qa-db-ja.com

Java 8 Stream APIは、プロパティ値に一致する一意のオブジェクトを検索します

Java 8 Streamを使用して、コレクションのプロパティ値と一致するオブジェクトを見つけます。

List<Person> objects = new ArrayList<>();

個人属性->名前、電話、電子メール。

Personsのリストを反復処理し、電子メールに一致するオブジェクトを見つけます。これはJava 8ストリームを介して簡単に実行できることを確認しました。しかし、それでもコレクションを返しますか?

例:

List<Person> matchingObjects = objects.stream.
    filter(p -> p.email().equals("testemail")).
    collect(Collectors.toList());

しかし、常に1つの一意のオブジェクトがあることを知っています。オブジェクトのリストを取得する代わりに、Collectors.toListの代わりに何かを実行して、実際のオブジェクトを直接取得できますか。

42
Santosh

コレクターを使用する代わりに、findFirstまたはfindAnyを使用してみてください。

Optional<Person> matchingObject = objects.stream().
    filter(p -> p.email().equals("testemail")).
    findFirst();

リストにはそのオブジェクトが含まれていない可能性があるため、これはOptionalを返します。

リストに常にその人が含まれていることが確実な場合は、電話をかけることができます。

Person person = matchingObject.get();

そのような人がいない場合にnullがわからない場合は、次を取得します。

Person person = matchingObject.orElse(null);

オプションには他にも便利な方法があります。 オプションのjavadoc をご覧ください。

87
Indrek Ots

findAnyorElse

findAny() および orElse() を使用して:

Person matchingObject = objects.stream().
filter(p -> p.email().equals("testemail")).
findAny().orElse(null);

オカレンスを見つけた後に検索を停止します。

findAny

Optional<T> findAny()

ストリームの一部の要素を説明するOptional、またはストリームが空の場合は空のOptionalを返します。これは、ターミナルの短絡動作です。この操作の動作は明示的に非決定的です。ストリーム内の任意の要素を自由に選択できます。これは、並列操作で最大限のパフォーマンスを実現するためです。コストは、同じソースでの複数の呼び出しが同じ結果を返さない可能性があることです。 (安定した結果が必要な場合は、代わりにfindFirst()を使用してください。)

Guava APIは MoreCollectors.onlyElement( )を提供します。これは厳密に1つの要素を含むストリームおよびその要素を返すを取るコレクターです。

返されるコレクターthrowsストリームの場合はIllegalArgumentException2つ以上の要素で構成される、およびストリームが空の場合はNoSuchElementException

使用法については、以下のコードを参照してください。

import static com.google.common.collect.MoreCollectors.onlyElement;

Person matchingPerson = objects.stream
                        .filter(p -> p.email().equals("testemail"))
                        .collect(onlyElement());
5
Sahil Chhabra