したがって、Name
オブジェクトとArrayList
(Name
)型のnames
があり、名前のリストにが含まれているかどうかを確認したい場合は、 Name
オブジェクト(n
)が与えられた場合、2つの方法で実行できます。
_boolean exists = names.contains(n);
_
または
_boolean exists - names.stream().anyMatch(x -> x.equals(n));
_
これら2つが同じように振る舞うかどうかを考えていて、nがnull
に割り当てられたらどうなるか考えましたか?
私が理解しているように、引数がnull
である場合、リストにtrue
が含まれている場合、null
を返します。これをどのように達成しますかanyMatch
-Objects.equals(x, n)
を使用することで実現できますか?
それが機能する場合、どのアプローチがより効率的です-それは怠[と並列性を利用できるのでanyMatch
ですか?
ストリームベースのバージョンの問題は、ifコレクション(したがってそのストリーム)にnull
要素が含まれているため、述語がNullPointerException
をスローしようとすることです。このequals
オブジェクトでnull
を呼び出します。
これは次の方法で回避できます
boolean exists = names.stream().anyMatch(x -> Objects.equals(x, n));
ただし、この場合、ストリームベースのソリューションに期待される実用的な利点はありません。並列処理はreally大きなリストに利点をもたらす可能性がありますが、mayを想定してあちこちでparallel()
を偶然スローするべきではありません物事を高速化します。まず、実際のボトルネックを明確に特定する必要があります。
そして読みやすさの観点から、私はここで最初の古典的な解決策を好むでしょう。 names.contains(aParticularValue)
のリストを確認したい場合は、これを行う必要があります-散文のように読み、意図を明確にします。
編集
contains
アプローチの別の利点は、コメントと他の回答で言及されており、ここで言及する価値があるかもしれません:names
コレクションのタイプが後で変更された場合、たとえばHashSet
にすると、contains
- check(O(1)の代わりにO(n))で高速になります無料-コードの他の部分を変更することなく。その場合、ストリームベースのソリューションはall要素を繰り返し処理する必要があり、これによりパフォーマンスが大幅に低下する可能性があります。
hashCode()
とequals()
が合理的な方法で記述されている場合、それらは同じ結果を提供するはずです。
ただし、パフォーマンスは完全に異なる場合があります。リストの場合はそれほど重要ではありませんが、HashSetの場合、contains()
はhashCode()
を使用して要素を特定し、(ほとんどの場合)一定の時間で実行されます。 2番目のソリューションでは、すべてのアイテムをループして関数を呼び出すため、線形時間で実行されます。
Nがnullの場合、通常equals()
メソッドはnull
引数を認識しているため、実際には問題ではありません。