2つのリストの共通要素


94

ArrayListそれぞれ3つの整数を持つ2つのオブジェクトがあります。2つのリストの共通要素を返す方法を見つけたいです。誰か私がこれをどのように達成できるか考えていますか?

回答:


160

を使用しCollection#retainAll()ます。

listA.retainAll(listB);
// listA now contains only the elements which are also contained in listB.

で変更が影響を受けlistAないようにする場合は、新しいものを作成する必要があります。

List<Integer> common = new ArrayList<Integer>(listA);
common.retainAll(listB);
// common now contains only the elements which are contained in listA and listB.

RetainAllは新しいリストを返しますか?そのtempList.addAll(listA.retainAll(listB));のような新しいリストに保存の出力を保存しようとしました。しかし、それは動作し
ません

1
後ろのリンクCollection#retainAll()とコードスニペットのコメントで答えたように、いいえ、そうではありません。変更は、メソッドを呼び出しているリストに反映されます。
BalusC、

問題は、リストcommonがサイズ3で初期化され、1つまたは2つの要素のみを返すことによってサイズを変更しようとすることです。私はあなたが提案したことを試みます、そしてそれは私を範囲外の例外として返します。
ゼニス炎

このアプローチでは、listB.retainAll(listA)を実行する場合、要素の出現回数を一致させることはできません。 、listBは{5,5}になりました...... listAとlistBを{5}として比較した後の最終結果が必要です。どうすればこれを達成できるかを親切に提案してください
NANCY 2015

1
コレクションオブジェクトの選択が不十分な場合、UnsupportedOperationExceptionがスローされる可能性があります。上記のArrayListの例はもちろん機能します。
デーモンゴレム2017年

39

ArrayListオブジェクトとの交差設定操作を使用できます。

このようなもの:

List<Integer> l1 = new ArrayList<Integer>();

l1.add(1);
l1.add(2);
l1.add(3);

List<Integer> l2= new ArrayList<Integer>();
l2.add(4);
l2.add(2);
l2.add(3);

System.out.println("l1 == "+l1);
System.out.println("l2 == "+l2);

List<Integer> l3 = new ArrayList<Integer>(l2);
l3.retainAll(l1);

    System.out.println("l3 == "+l3);

これで、とのl3間の共通要素のみが含まれるはずです。l1l2

CONSOLE OUTPUT
l1 == [1, 2, 3]
l2 == [4, 2, 3]
l3 == [2, 3]

6
この方法で変更が反映さl2れることに注意してください。あなたはおそらくList<Integer> l3 = new ArrayList<Integer>(l2);代わりに言うつもりでした。
BalusC

l1に2つの要素があり、l2に同じ要素が3つある場合、問題は少し面倒になります。要素がl1に2回しか含まれていない場合でも、retainAllはその要素の3つをl3に入れます。
demongolem

35

なぜ車輪を再発明するのですか?Commonsコレクションを使用する:

CollectionUtils.intersection(java.util.Collection a, java.util.Collection b)

これは優れたソリューションですが、前述のとおり、retainAll()繰り返し要素とは異なる動作をします。そのため、問題への取り組み方に応じて、おそらく1つは正しく、もう1つは正しくありません。
デモンゴレム2016年

17

Java 8のStream.filter()メソッドを以下と組み合わせて使用しますList.contains()

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

/* ... */

List<Integer> list1 = asList(1, 2, 3, 4, 5);
List<Integer> list2 = asList(1, 3, 5, 7, 9);

List<Integer> common = list1.stream().filter(list2::contains).collect(toList());

4
コンパイラーが何か賢いことをしない限り、n()回呼び出されるO(n)操作のように見えます。上記が線形または二次時間で実行されるかどうか誰かが知っていますか?
Regorsmitz

1
それは* n操作になるでしょう!
ラクシュミカントデシュパンデ2017

5

ここに画像の説明を入力してください

            List<String> lista =new ArrayList<String>();
            List<String> listb =new ArrayList<String>();

            lista.add("Isabella");
            lista.add("Angelina");
            lista.add("Pille");
            lista.add("Hazem");

            listb.add("Isabella");
            listb.add("Angelina");
            listb.add("Bianca");

            // Create an aplusb list which will contain both list (list1 and list2) in which common element will occur twice 
            List<String> listapluslistb =new ArrayList<String>(lista);    
            listapluslistb.addAll(listb);

            // Create an aunionb set which will contain both list (list1 and list2) in which common element will occur once
            Set<String> listaunionlistb =new HashSet<String>(lista);
            listaunionlistb.addAll(listb);

            for(String s:listaunionlistb)
            {
                listapluslistb.remove(s);
            }
            System.out.println(listapluslistb);

このコードは質問に答えることがありますが、問題を解決する方法および/または理由に関する追加のコンテキストを提供すると、回答の長期的な価値が向上します。
マイケルパーカー

5
List<Integer> listA = new ArrayList<>();
    listA.add(1);
    listA.add(5);
    listA.add(3);
    listA.add(4);   

List<Integer> listB = new ArrayList<>();
    listB.add(1);
    listB.add(5);
    listB.add(6);
    listB.add(7);
System.out.println(listA.stream().filter(listB::contains).collect(Collectors.toList()));


Java 1.8 Stream API Solutions

出力[1、5]


-Improvementweは、リストをList <Integer>として定義できますlistA = asList(1、5、3、4); List <Integer> listB = asList(1、5、6、7);
Rajeev Ranjan

4

メソッド「retainAll」を使用して、2つのリスト間の共通要素を取得できます。このメソッドは、それが適用されるリストからすべての一致しない要素を削除します。

Ex.: list.retainAll(list1);

この場合、リストから、list1にないすべての要素が削除され、listとlist1の間で共通の要素のみが残ります。

List<Integer> list = new ArrayList<>();
list.add(10);
list.add(13);
list.add(12);
list.add(11);

List<Integer> list1 = new ArrayList<>();
list1.add(10);
list1.add(113);
list1.add(112);
list1.add(111);
//before retainAll
System.out.println(list);
System.out.println(list1);
//applying retainAll on list
list.retainAll(list1);
//After retainAll
System.out.println("list::"+list);
System.out.println("list1::"+list1);

出力:

[10, 13, 12, 11]
[10, 113, 112, 111]
list::[10]
list1::[10, 113, 112, 111]

注:retainAllをリストに適用すると、リストにはlistとlist1の間の共通要素が含まれます。


4
public <T> List<T> getIntersectOfCollections(Collection<T> first, Collection<T> second) {
        return first.stream()
                .filter(second::contains)
                .collect(Collectors.toList());
    }

3
    // Create two collections:
    LinkedList<String> listA =  new LinkedList<String>();
    ArrayList<String> listB =  new ArrayList<String>();

    // Add some elements to listA:
    listA.add("A");
    listA.add("B");
    listA.add("C");
    listA.add("D");

    // Add some elements to listB:
    listB.add("A");
    listB.add("B");
    listB.add("C");

    // use 

    List<String> common = new ArrayList<String>(listA);
    // use common.retainAll

    common.retainAll(listB);

    System.out.println("The common collection is : " + common);

3

2つのリストL1とL2を考える

Java8を使用すると、簡単に見つけることができます

L1.stream().filter(L2::contains).collect(Collectors.toList())


1

自分でやりたい場合に。

List<Integer> commons = new ArrayList<Integer>();

for (Integer igr : group1) {
    if (group2.contains(igr)) {
        commons.add(igr);
    }
}

System.out.println("Common elements are :: -");
for (Integer igr : commons) {
    System.out.println(" "+igr);
}

1
OPは、共通の要素がいくつあるかではなく、どの要素が共通であるかを見つける方法を求めていました。
Brendon Dugan 2013

@BrendonDugan-それはこのコードが行うことです。リストにcommonsは、共通の要素が含まれています。2番目のforループは、それらをコンソールに出力します。コードが共通要素を数えているところがわかりません。
Ajoy Bhatia 2016年

@AjoyBhatia-(2013年に)私がコメントしたとき、コードは一般的な要素の数のみを返しました。
Brendon Dugan

@BrendonDuganああ、そうか。申し訳ありません。回答はその場で編集できますが、コメントは通常、時系列でそのまま残されます:-)
Ajoy Bhatia

0

上記の回答の一部は類似していますが同じではないため、新しい回答として投稿してください。

解決策:
1.削除する必要がある要素を保持するためにHashSetを使用します
2. list1のすべての要素をHashSetに追加します
3. list2を反復し、list1とlist2の両方に存在するlist2 ==>に存在するHashSetから要素を削除します
4 。次に、HashSetを反復処理し、list1から要素を削除します(list1のすべての要素を設定に追加したため)。最後に、list1にすべての共通要素があります。
注:list2のすべての要素を追加できます。3回目の反復で、要素を削除する必要があります。リスト2。

時間の複雑さ:O(n)
空間の複雑さ:O(n)

コード:

import com.sun.tools.javac.util.Assert;
import org.apache.commons.collections4.CollectionUtils;

    List<Integer> list1 = new ArrayList<>();
    list1.add(1);
    list1.add(2);
    list1.add(3);
    list1.add(4);
    list1.add(5);

    List<Integer> list2 = new ArrayList<>();
    list2.add(1);
    list2.add(3);
    list2.add(5);
    list2.add(7);
    Set<Integer> toBeRemoveFromList1 = new HashSet<>(list1);
    System.out.println("list1:" + list1);
    System.out.println("list2:" + list2);
    for (Integer n : list2) {
        if (toBeRemoveFromList1.contains(n)) {
            toBeRemoveFromList1.remove(n);
        }
    }
    System.out.println("toBeRemoveFromList1:" + toBeRemoveFromList1);
    for (Integer n : toBeRemoveFromList1) {
        list1.remove(n);
    }
    System.out.println("list1:" + list1);
    System.out.println("collectionUtils:" + CollectionUtils.intersection(list1, list2));
    Assert.check(CollectionUtils.intersection(list1, list2).containsAll(list1));

出力:

list1:[1, 2, 3, 4, 5]
list2:[1, 3, 5, 7]
toBeRemoveFromList1:[2, 4]
list1:[1, 3, 5]
collectionUtils:[1, 3, 5]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.