web-dev-qa-db-ja.com

順序に関係なく、2つのコレクションに同じ要素が含まれているかどうかを確認する方法は?

以下に示すように2つの異なるハッシュセットがあるとします。2つのハッシュセットが同じ要素を含み、これらの2つのハッシュセットが等しいことを、コレクション内の要素の順序とは無関係に確認するにはどうすればよいですか。

Set set1=new HashSet();
          set.add(new Emp("Ram","Trainer",34000));
          set.add(new Emp("LalRam","Trainer",34000));

もう1つは..

Set set2=new HashSet();
          set.add(new Emp("LalRam","Trainer",34000));
          set.add(new Emp("Ram","Trainer",34000));

社員ポジョは...

class Emp //implements Comparable
{
      String name,job;
      public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getJob() {
        return job;
    }
    public void setJob(String job) {
        this.job = job;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    int salary;
      public Emp(String n,String j,int sal)
      {
         name=n;
         job=j;
         salary=sal;
       }
      public void display()
      {
        System.out.println(name+"\t"+job+"\t"+salary);
       }



  public boolean equals(Object o)
      {

         Emp p=(Emp)o;
          return this.name.equals(p.name)&&this.job.equals(p.job) &&this.salary==p.salary;
       }
   public int hashCode()
       {
          return name.hashCode()+job.hashCode()+salary;
       }


      /* public int compareTo(Object o)
       {
          Emp e=(Emp)o;
          return this.name.compareTo(e.name);
           //return this.job.compareTo(e.job);
        //   return this.salary-e.salary;

        }*/
} 
11
user1582269

AbstractSet.equals(Object) javadocからの引用:

指定されたオブジェクトがセットでもあり、2つのセットのサイズが同じで、指定されたセットのすべてのメンバーがこのセットに含まれている場合は、trueを返します。これにより、Setインターフェースの異なる実装間でequalsメソッドが正しく機能することが保証されます。

したがって、set1.equals(set2)を呼び出すだけで十分です。セットに同じ要素が含まれている場合にのみtrueを返します(セット内のオブジェクトにequalshashCodeを正しく定義した場合)。

89
Petr Pudlák

次の式を使用します。

set1.containsAll(set2) && set2.containsAll(set1)
11
Aaron Kurtzhals

イコールとハッシュコードを定義したとすると、ここに1つの方法があります。大きなメンバーにはあまり効率的ではありません。

  1. それぞれの要素の数を確認してください。それらが等しくない場合、あなたは[等しくない]で終了です。
  2. Set1をループします。 Set2に各要素が含まれているかどうかを確認します。含まれていない場合は[等しくない]です。そうでなければ、セット全体を通過した場合、あなたは平等です

更新:私はcontainsAllについて知りませんでした。これは多くのトラブルを節約し、基本的にそのアルゴリズムを行います

int s1 = set1.size();
int s2 = set2.size();
if (s1 !=s2) return false;
return set1.containsAll(set2);
8
MJB

データの等価性が必要な場合は、equals()およびhashCode()を正しく実装してから、 Collection.containsAll(...) を使用できます。もちろん、両方のコレクションの要素数が同じである場合にのみこれを呼び出す必要があります。そうでない場合は、それらが等しくないと言うことができます。

4

行う:

  setResult = set2.clone();

  if ( setResult.retainAll( set1 ) ){

   //do something with results, since the collection had differences

}
0
Edmon

コレクションのタイプがわからない場合の冗長ですが(うまくいけば)効率的なソリューションです。

public static <T> boolean equalIgnoreOrder(Collection<T> c1, Collection<T> c2) {
    int size1 = c1.size();  // O(1) for most implementations, but we cache for the exceptions.
    if (size1 != c2.size()) {
        return false;
    }
    Set<T> set;
    Collection<T> other;
    if (c1 instanceof Set) {
        set = (Set<T>) c1;
        other = c2;
    } else if (c2 instanceof Set) {
        set = (Set<T>) c2;
        other = c1;
    } else if (size1 < 12 ) { // N^2 operation OK for small N
        return c1.containsAll(c2);
    } else {
        set = new HashSet<>(c1);
        other = c2;
    }
    return set.containsAll(other);  // O(N) for sets
}
0
Tad

1-1つのコレクションが持っているアイテムと別のコレクションが持っていないアイテムを含むコレクションを取得します(名前を 'differences'とします)-

コレクションの違い= CollectionUtils.subtract(Collection1、Collection2);

2-サイズ== 0であることを確認します。

その場合-両方のコレクションに同じ要素があります。いいえの場合-いくつかの違いがあり、「違い」があるすべてのアイテムを印刷する必要があります。

アイテムの注文に依存するかどうかは不明です。この方法でコレクションを比較しています

0
Vladislav Filin