user1582269
user1582269

Reputation: 305

Way to check if two Collections contain the same elements, independent of order?

Let say I have two different hashsets as shown below how can I check that two Hashset contain the same elements and these two hashsets are equal, independent of the order of elements in collection, please advise..!!

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

and the other one is ..

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

The employee pojo is ...

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;

        }*/
} 

Upvotes: 16

Views: 60265

Answers (8)

Tad
Tad

Reputation: 4784

A verbose but (hopefully) efficient solution when you don't know the types of the 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
}

Upvotes: 0

Vladislav Filin
Vladislav Filin

Reputation: 11

1 - Get a collection(let's name it 'differences') that will contain items one collection has and another doesn't -

Collection differences = CollectionUtils.subtract(Collection1, Collection2);

2 - Check that size == 0;

If so - both collections have same elements; if no - there's some differences and then you have to print all items that 'differences' has.

Not sure if it depends on items order. I'm comparing collections in this way

Upvotes: 0

nyanshak
nyanshak

Reputation: 68

Unless you need to implement your own method for some reason, just use h1.equals(h2). A possible implementation is described below.

  1. Check if # of elements is the same. If not, return false.
  2. Clone set 2 (if you need to keep set 2 after)
  3. Iterate through set 1, check if each element is found in clone set 2. If found, remove from set 2. If not found, return false.
  4. If you reach the end of the iterations and have matched each element of set 1, the sets are equal (since you already compared the sizes of the 2 sets).

Example:

public boolean isIdenticalHashSet <A> (HashSet h1, HashSet h2) {
    if ( h1.size() != h2.size() ) {
        return false;
    }
    HashSet<A> clone = new HashSet<A>(h2); // just use h2 if you don't need to save the original h2
    Iterator it = h1.iterator();
    while (it.hasNext() ){
        A = it.next();
        if (clone.contains(A)){ // replace clone with h2 if not concerned with saving data from h2
            clone.remove(A);
        } else {
            return false;
        }
    }
    return true; // will only return true if sets are equal
}

Upvotes: -6

MJB
MJB

Reputation: 9399

Assuming you've defined equals and hashcode, here's one way. Not very efficient for large members.

  1. Check the # of elements in each. If they are not equal, you are done [not equal].
  2. Loop through Set1. Check if Set2 contains each element, if not you are done [not equal]. otherwise if you get through the whole set, you are equal

UPDATE: I didn't know about containsAll, which saves a lot of trouble and basically does that algorithm

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

Upvotes: 11

Petr
Petr

Reputation: 63359

Quoting from AbstractSet.equals(Object) javadoc:

Returns true if the given object is also a set, the two sets have the same size, and every member of the given set is contained in this set. This ensures that the equals method works properly across different implementations of the Set interface.

So it's sufficient to simply call set1.equals(set2). It will return true if and only if the set contain the same elements (assuming that you have correctly defined equals and hashCode on the objects in the sets).

Upvotes: 105

Aaron Kurtzhals
Aaron Kurtzhals

Reputation: 2036

Use the below expression.

set1.containsAll(set2) && set2.containsAll(set1)

Upvotes: 10

Edmon
Edmon

Reputation: 4872

Do:

  setResult = set2.clone();

  if ( setResult.retainAll( set1 ) ){

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

}

Upvotes: 0

Aravind Yarram
Aravind Yarram

Reputation: 80176

If you want data equality then correctly implement equals() and hashCode() and then you can use Collection.containsAll(...). Ofcourse, you need to make sure you call this only when both of your collections have the same number of elements otherwise you can just say they aren't equal.

Upvotes: 4

Related Questions