2016-04-16 12 views
3

list2のオブジェクトのいずれかがlist1に存在するかどうかを比較したいと考えています。Stream-anyMatchを使用した2つのコレクションの比較

私は両方のリストを繰り返して、.contains()を使ってすべての要素を比較することができましたが、より効率的な方法がないかどうか疑問に思っています。私はthis発見し、私は提案された方法を実装しようとしています:私はこれを行うと、私はtrueを期待しても、私は常にfalseを得る

List<Item> list1; 
List<Item> list2; 

boolean anyMatch = list1.stream().anyMatch(x -> x.equals(list2.stream())); 
System.out.println(anyMatch); 

を。どうして?

+0

湯気が足場の多くを持っていることを唯一の5文字短いです怠惰な評価のために状態を維持する。 –

+1

list1の要素とlist2のストリームを比較しています。彼らは同じ種類のものでもありません。ストリームでは何も速くしません。 list1.equals(list2)を使うことができますが、順序は重要です。注文が問題ではなく、アイテムが一意である場合は、リストの代わりにセットを使用します。 –

+0

@屯木リストになっているはずです。 list2のオブジェクトがlist1に存在するかどうかを比較したいと思います。 明確になったはずです。 – k88

答えて

6

あなたのコメントには、list1list2という2つのリストがあります。 list2の要素のうちの少なくとも1つがlist1に含まれているかどうかを調べる必要があります。

ストリームAPIを使用すると、list2Streamを取得できます。次に、anyMatch(predicate)コールは、このストリームの要素の1つが指定された述語と一致するかどうかを返します。この場合、要素がlist1に含まれているかどうかがテストされます。

boolean anyMatch = list2.stream().anyMatch(list1::contains); 

これは、述語としてmethod referenceを使用します。

あなたは、一定時間のルックアップを保証する、Setlist1を変換することにより、より優れた性能を持っているでしょう:

boolean anyMatch = list2.stream().anyMatch(new HashSet<>(list1)::contains); 
+0

まさに私が探していたものです。ありがとう! – k88

5

@Tunaki's answerが正しいですが、ここでは(それがStream.anyMatch()を使用していない別のより簡潔な方法がありますしかしこの方法、):

boolean anyMatch = !Collections.disjoint(list1, list2); 

これは、2つのコレクションに共通の要素が存在しないときtrueを返すCollections.disjoint()方法を、使用しています。

Tunakiさんのコメントについてのパフォーマンスもここに適用されます:パフォーマンス向上のために、最高のは、その方法がO(1)平均であるため、HashSetにあなたのlist1を回すことであろう。 Collections.disjoint()メソッドは、実際にはその引数のいずれかがSetであるかどうかをチェックし、Set以外のコレクションを反復処理します。

boolean anyMatch = !Collections.disjoint(new HashSet<>(list1), list2); 

注:だからあなたの場合には、あなたがしなければならないすべてはあなたのlist1からHashSetを作成された後、すべて、私の答えはTunakiの:)

+0

これを達成する別の方法を示してくれてありがとう。リストを 'HashSet'に変換すると、両方のメソッドが同じ性能を持つと思いますか? – k88

+1

@ k88ストリームがシーケンシャルの場合、パフォーマンスは同等です。パラレルの場合、リストに要素がたくさんある場合(数千個以上の場合、テストする必要があります。マシンによって異なります)、パフォーマンスは向上します。また、最高のパフォーマンスを得るためには、より多くの要素を持つリストを 'HashSet'に変換し、もう一方を反復する必要があります。 –

関連する問題