Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintaining hashCode contract for the specific condition, equals() depending on two integers

I have a basic class with the structure:

class Employee {
int eId;
String eName;

Employee(int id, String name) {
    this.eId= id;
    this.eName= name;
}

The conditions for equality is such that equals() should return true if any of the following is true:

  1. eId are same.
  2. eName are same.
  3. Lengths of eName are same.

I had no problem in overriding equals(), however, in order to maintain the hash code contract, I should override hashCode() as well. So, the hashCode should depend on eId and eName.length() (if eNames are equal, their lengths will be equal as well). So there are four cases:

Employee e1 = new Employee(4, "John");
Employee e2 = new Employee(3, "Jane");
Employee e3 = new Employee(4, "Jim");
Employee e4 = new Employee(7, "Random");

hashCode() should return the same value for e1, e2, and e3 and a different value for e4. I can't come up with the logic satisfying this requirement.

Here is the exact problem:

Create a class (having parameters name, id etc). Show that if 2 objects of this class will be compared then they should return true in any of below case :

A. Id of both are same.

B. Name of both are same.

C. Length of name’s of both are same.

Make sure HashCode contract should not violate.

like image 795
neo.one Avatar asked Dec 03 '25 17:12

neo.one


1 Answers

You're running into trouble because your notion of equality is inconsistent. Specifically, it's not transitive, which the contract for .equals() requires.

It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.

Under your definition, e1 equals e2 and e3, but e2 does not equal e3. This is incompatible with Java's notion of equality. This is also why you're running into trouble defining a reasonable .hashCode() implementation.

However what you can do is define a custom Comparator (or Ordering, if you're using Guava). For most use cases (like sorting, searching, or filtering) you should be able to use a separate Comparator instance just like you would the .equals() method. You are effectively trying to define equivalent objects, not equal objects.

If you can't use a separate Comparator for whatever reason, your Employee object will be fundamentally inconsistent, and will prove problematic even if you should get a "workable" .hashCode() implemented.

like image 60
dimo414 Avatar answered Dec 06 '25 06:12

dimo414



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!