Javaが2つのリストを比較する


92

私は2つのリストを持っています(Javaリストではなく、2つの列を言うことができます)

例えば

**List 1**            **Lists 2**
  milan                 hafil
  dingo                 iga
  iga                   dingo
  elpha                 binga
  hafil                 mike
  meat                  dingo
  milan
  elpha
  meat
  iga                   
  neeta.peeta    

同じ要素の数を返すメソッドが欲しいのですが。この例の場合は3で、リストと異なる値の両方の同様の値が返されます。

はいの場合はハッシュマップを使用する必要がありますか?結果を取得するにはどのような方法ですか?

助けてください

PS:それは学校の課題ではありません:)それであなたが私を導くだけならそれで十分です


リストがJavaリストでもハッシュマップでもデータ構造でもないデータ構造を提案してください
user238384

1
例外的なケースで何をすべきかを必ず考えてください。リストに同じ値を2回含めることはできますか?もしそうなら、「ディンゴ」が両方のリストに2回ある場合、それは共通の2つの要素としてカウントされますか、それとも1つだけとしてカウントされますか?
JavadocMD 2010年

リストの1つを変更できますか?
Anthony Forloney

編集する方法?はい、各リストには同じような値を複数回含めることができます
user238384

質問の直後、タグの下に編集用の小さなリンクがあるはずです。
OscarRyz

回答:


159

編集する

ここに2つのバージョンがあります。1つの使用ArrayListおよび他の使用HashSet

それらを比較し、必要なものが得られるまで、これから独自のバージョンを作成してください。

これで十分です:

PS:それは学校の課題ではありません:)それであなたが私を導くだけならそれで十分です

あなたの質問の一部。

元の答えを続けます:

そのためにjava.util.Collection および/または java.util.ArrayListを使用できます。

がretainAllの方法は、次の処理を行います。

指定されたコレクションに含まれるこのコレクションの要素のみを保持します

このサンプルを参照してください:

import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;

public class Repeated {
    public static void main( String  [] args ) {
        Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
        Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));

        listOne.retainAll( listTwo );
        System.out.println( listOne );
    }
}

編集する

2番目の部分(同様の値)には、removeAllメソッドを使用できます。

指定されたコレクションにも含まれているこのコレクションの要素をすべて削除します。

この2番目のバージョンでは、同様の値とハンドルが繰り返されます(それらを破棄することにより)。

今回はCollectiona Setではなくaである可能性がありますList(違いは、セットは繰り返し値を許可しない)

import java.util.Collection;
import java.util.HashSet;
import java.util.Arrays;

class Repeated {
      public static void main( String  [] args ) {

          Collection<String> listOne = Arrays.asList("milan","iga",
                                                    "dingo","iga",
                                                    "elpha","iga",
                                                    "hafil","iga",
                                                    "meat","iga", 
                                                    "neeta.peeta","iga");

          Collection<String> listTwo = Arrays.asList("hafil",
                                                     "iga",
                                                     "binga", 
                                                     "mike", 
                                                     "dingo","dingo","dingo");

          Collection<String> similar = new HashSet<String>( listOne );
          Collection<String> different = new HashSet<String>();
          different.addAll( listOne );
          different.addAll( listTwo );

          similar.retainAll( listTwo );
          different.removeAll( similar );

          System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nDifferent:%s%n", listOne, listTwo, similar, different);
      }
}

出力:

$ java Repeated
One:[milan, iga, dingo, iga, elpha, iga, hafil, iga, meat, iga, neeta.peeta, iga]

Two:[hafil, iga, binga, mike, dingo, dingo, dingo]

Similar:[dingo, iga, hafil]

Different:[mike, binga, milan, meat, elpha, neeta.peeta]

必要なことが正確に実行されない場合は、ここから処理できるように、適切なスタートを切ることができます。

読者への質問:繰り返されるすべての値をどのように含めますか?


@オスカー、私の考えは正確ですが、の内容を変更できるかどうかはわかりませんでしたがlistOne、とにかく+1しました!
Anthony Forloney

@poygenelubricants ジェネリックではなく生の型とはどういう意味ですか?何故なの?
OscarRyz

オスカー、更新された質問を見ましたか?繰り返し値をサポートしていますか?
user238384

@Oscar:java.sun.com/docs/books/jls/third_edition/html/… "Javaプログラミング言語へのジェネリック性の導入後に記述されたコードでのraw型の使用は強く推奨されていません。将来のバージョンのJavaプログラミング言語では、生の型を使用できません。」
polygenelubricants

2
@polygenelubricantsの回答は、重複および未処理のタイプを処理するように更新されました。ところで、Javaの..将来のバージョンは決して起こりません。;)
OscarRyz

37

あなたは試すことができますintersection()subtract()のメソッドCollectionUtils

intersection()メソッドは共通の要素を含むコレクションをsubtract()提供し、メソッドはすべての非共通の要素を提供します。

彼らはまた、同様の要素の世話をする必要があります


5
このソリューションにはApache Ccommonsが必要であることに注意してください
Codesalot卿2018年

9

これらは本当にリスト(順序付き、重複あり)ですか、それともセット(順序なし、重複なし)ですか?

後者の場合は、たとえばa java.util.HashSet<E>を使用して、便利なを使用して予想される線形時間でこれを実行できるためretainAllです。

    List<String> list1 = Arrays.asList(
        "milan", "milan", "iga", "dingo", "milan"
    );
    List<String> list2 = Arrays.asList(
        "hafil", "milan", "dingo", "meat"
    );

    // intersection as set
    Set<String> intersect = new HashSet<String>(list1);
    intersect.retainAll(list2);
    System.out.println(intersect.size()); // prints "2"
    System.out.println(intersect); // prints "[milan, dingo]"

    // intersection/union as list
    List<String> intersectList = new ArrayList<String>();
    intersectList.addAll(list1);
    intersectList.addAll(list2);
    intersectList.retainAll(intersect);
    System.out.println(intersectList);
    // prints "[milan, milan, dingo, milan, milan, dingo]"

    // original lists are structurally unmodified
    System.out.println(list1); // prints "[milan, milan, iga, dingo, milan]"
    System.out.println(list2); // prints "[hafil, milan, dingo, meat]"

まあ、どのデータ構造にするべきか本当にわかりません。重複しています。これで、更新された質問を見ることができます
user238384

データセットから繰り返し値を削除しますか?coz値を失いたくありません:(
user238384

@agazerboy:私は両方の質問に対処しようとしました。詳細についてはお気軽にお問い合わせください。
polygenelubricants

ありがとうポリ。たとえば、最初のリストで重複してプログラムを試しましたが、「iga」を2回追加しましたが、それでも3が返されます。現在は4です。cozリスト1には4つの類似した値があります。1つのエントリを複数回追加した場合、機能するはずです。あなたは何を言っていますか?他のデータ構造?
user238384

6

Java 8 removeIfの使用

public int getSimilarItems(){
    List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
    List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
    int initial = two.size();

    two.removeIf(one::contains);
    return initial - two.size();
}

見た目は良いですが、リストを変更せずに保持したい場合は、リストの1つを複製する必要があり、特定のケースではそれが望ましくありません。
Sebastian D'Agostino 2017年

6

2つのコレクションが等しいかどうかをテストする便利な方法を探している場合org.apache.commons.collections.CollectionUtils.isEqualCollectionは、順序に関係なく2つのコレクションを比較するを使用できます。


4

すべてのアプローチの中で、私は使用することorg.apache.commons.collections.CollectionUtils#isEqualCollectionが最善のアプローチだと思います。ここに理由があります-

  • 追加のリストを宣言したり、自分で設定したりする必要はありません
  • 入力リストを変更していません
  • それは非常に効率的です。O(N)の複雑さの同等性をチェックします。

apache.commons.collections依存関係として持つことができない場合は、効率が良いため、リストが等しいかどうかをチェックするためのアルゴリズムを実装することをお勧めします。


3

シンプルなソリューション:-

    List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "d", "c"));
    List<String> list2 = new ArrayList<String>(Arrays.asList("b", "f", "c"));

    list.retainAll(list2);
    list2.removeAll(list);
    System.out.println("similiar " + list);
    System.out.println("different " + list2);

出力:-

similiar [b, c]
different [f]

1

仮定hash1hash2

List< String > sames = whatever
List< String > diffs = whatever

int count = 0;
for( String key : hash1.keySet() )
{
   if( hash2.containsKey( key ) ) 
   {
      sames.add( key );
   }
   else
   {
      diffs.add( key );
   }
}

//sames.size() contains the number of similar elements.

彼は、同一のキーの数ではなく、同一のキーのリストを必要としています。おもう。
Rosdi Kasim

ステファン、助けてくれてありがとう。ああ、Rosdiは正しいし、あなたもそうだ。同様の値の合計数と同様の値も必要です。
user238384

1

私は、リストの比較の非常に基本的な例で見つかったリストが比較 第一の例の検証大きさをして、別の1つのリストの特定の要素の可用性をチェックします。


-1
public static boolean compareList(List ls1, List ls2){
    return ls1.containsAll(ls2) && ls1.size() == ls2.size() ? true :false;
     }

public static void main(String[] args) {

    ArrayList<String> one = new ArrayList<String>();
    one.add("one");
    one.add("two");
    one.add("six");

    ArrayList<String> two = new ArrayList<String>();
    two.add("one");
    two.add("six");
    two.add("two");

    System.out.println("Output1 :: " + compareList(one, two));

    two.add("ten");

    System.out.println("Output2 :: " + compareList(one, two));
  }

1
2つに「1つ」の3つのコピーが含まれている場合、このソリューションは誤った結果を返します。それは誤って真の結果を生成します。
ジョセフフィッツジェラルド

この部分をありがとう:&& ls1.size()== ls2.size()
Nouar

1
? true :falseスニペットで必要と思われる理由はありますか?
Krzysztof Tomaszewski
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.