Jack Allan
Jack Allan

Reputation: 15004

Java: Selective comparison of two sets

I am writing a lot of unit tests that do similar things with but with different classes.

I want to compare Sets of the same class. The class specifies an id property. In set A this property is all null. In Set B this property is set. (Set B has been persisted to a database and uids have been populated).

For my unit test I want to make sure that Set A matches Set B and I obviously don't want it to look at the id field.

What is the most efficient, clean and DRY way of doing this?

Upvotes: 0

Views: 1504

Answers (4)

Mawia
Mawia

Reputation: 4310

Comparison for duplicate items logic is achieved in Java using the equals() method.

myString.equals("compare this");

When you need to compare objects of your custome types, you have to override equals method.

Student student1=new Student();
Student student2=new Student();
student1.equals(student2);

But be careful when you override equals() method. You need to provide some basis of comparison based on some unique ids. For instance, the following implementation uses the Roll number as a unique id for comparison

public class Student {

  private int rollNo;
  private String name;
  private String address;


    // Getters and Setters

@Override
  public int hashCode() {
   // Overide this only when you use Hashing implementations
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
      System.out.println("Not Equal due to NULL");
      return false;
    }
    if (this == obj) {
      System.out.println("Equals due to same reference");
      return true;
    }
    if (getClass() != obj.getClass()) {
      System.out.println("Different Type");
      return false;
    }
    Student other = (Student) obj;
    if (rollNo == other.rollNo) {
      System.out.println("RollNo " + rollNo + " EQUALS " + other.rollNo);
      return true;
    }
    if (rollNo != other.rollNo) {
      System.out.println("RollNo " + rollNo + " NOT EQUALS " + other.rollNo);
      return false;
    }
    System.out.println("Default is FALSE");
    return false;
  }

}

Upvotes: 0

MaDa
MaDa

Reputation: 10762

First of all, compare two sets' sizes, if they're not equal, test fails.

For a non-trivial case, ddefine a java.util.Comparator for set elements, sort both according to this comparator (you can include/omit the property by which you don't want to compare). Then iterate over both sets, comparing elements based on your rules (different from the ones defined by the comparator, if I understand correctly your point).

I assume you already have your equals and hashCode methods properly defined and don't want to change them for the sake of the test.

Upvotes: 1

Rahul
Rahul

Reputation: 45070

You can override the equals() & hashCode() method in your class and then use removeAll() method to remove all the elements from Set B. Post this, if the set is empty, then they match, else they don't.

Note that the overridden methods should have the logic, which doesn't involveid.

Upvotes: 0

Krushna
Krushna

Reputation: 6060

You need to override the hashCode() and equals() method of the classes where you should not include the id field in both the method then the equals method Set will work how you want.

for Example,

class  Test{

int id;
String name;
String other;
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + ((other == null) ? 0 : other.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Test other = (Test) obj;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    if (this.other == null) {
        if (other.other != null)
            return false;
    } else if (!this.other.equals(other.other))
        return false;
    return true;
}

}

Now the Test class object are not dependent on ID. You can very easily generate the equlas and hashCode method using a IDE like Eclipse.

Upvotes: 0

Related Questions