web-dev-qa-db-fra.com

Manière de vérifier si deux collections contiennent les mêmes éléments, indépendamment de l'ordre?

Supposons que je dispose de deux hashsets différents, comme indiqué ci-dessous. Comment puis-je vérifier que deux hachages contiennent les mêmes éléments et que ces deux hashsets sont égaux, indépendamment de l'ordre des éléments de la collection, veuillez en aviser .. !!

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

et l'autre est ..

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

Le pojo employé est ...

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;

        }*/
} 
10
user1582269

Citation de AbstractSet.equals (Object) javadoc:

Renvoie true si l'objet donné est également un ensemble, les deux ensembles ont la même taille Et chaque membre de cet ensemble est contenu dans cet ensemble. Ceci garantit le bon fonctionnement de la méthode equals à travers différentes implémentations de l'interface Set.

Il suffit donc d'appeler simplement set1.equals(set2). Il renverra true si et seulement si l'ensemble contient les mêmes éléments (en supposant que vous avez correctement défini equals et hashCode sur les objets des ensembles).

88
Petr Pudlák

Utilisez l'expression ci-dessous.

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

En supposant que vous définissiez égaux et hashcode, voici une solution. Pas très efficace pour les gros membres.

  1. Vérifiez le nombre d'éléments dans chacun. S'ils ne sont pas égaux, vous avez terminé [pas égaux].
  2. Boucle à travers Set1. Vérifiez si Set2 contient chaque élément, sinon vous avez terminé [pas égal]. sinon, si vous passez à travers l'ensemble, vous êtes égal

UPDATE: Je ne savais pas que contientTous, ce qui évite beaucoup de problèmes et utilise cet algorithme

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

Si vous voulez l'égalité des données, implémentez correctement les fonctions equals() et hashCode(). Vous pouvez ensuite utiliser Collection.containsAll (...) . Bien sûr, vous devez vous assurer de ne l'appeler que lorsque vos deux collections contiennent le même nombre d'éléments, sinon vous pouvez simplement dire qu'elles ne sont pas égales.

4
Aravind R. Yarram

Faire:

  setResult = set2.clone();

  if ( setResult.retainAll( set1 ) ){

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

}
0
Edmon

Une solution verbeuse mais (heureusement) efficace lorsque vous ne connaissez pas les types de collections:

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 - Obtenez une collection (appelons-la 'différences') qui contiendra les éléments d'une collection et d'une autre - 

Différences de collection = CollectionUtils.subtract (Collection1, Collection2);

2 - Vérifiez cette taille == 0;

Si tel est le cas - les deux collections comportent les mêmes éléments; Si non - il existe des différences et vous devez ensuite imprimer tous les éléments ayant des "différences".

Je ne sais pas si cela dépend de l'ordre des articles. Je compare les collections de cette façon

0
Vladislav Filin