2

I have (at least) two classes that implement the same interface and have the same fields. Is it ok if those two classes have the same hash code if their fields are identical or should they be different? Is this code ok?

interface Base { }

class A implements Base {
  private Integer value;

  public A(Integer value) { this.value = value; }

  public int hashCode() { return value.hashCode(); }
}

class B implements Base {
  private Integer value;

  public B(Integer value) { this.value = value; }

  public int hashCode() { return value.hashCode(); }
}
MadScientist
  • 3,390
  • 15
  • 19
  • Why would you have two classes of it? – Murat Karagöz Nov 05 '18 at 14:33
  • It is fine for them to have similar `hashCode` implementations if it makes sense for both of them. Though from your question it's somewhat unclear what the purpose of these two classes is. – khelwood Nov 05 '18 at 14:37
  • The only requirement for `hashCode` is that `A.equals(B) ==> A.hashCode() == B.hashCode()`. Also: you should always modify both `hashCode` and `equals` together to keep that requirement... Obviously doing this will have implications. For example Python does this with numbers classes so that integer `1` is equal to float `1.0`, but this implies that if you have a map like `{1: "a"}` then you can use `1.0` in place of `1` to fetch that value and you cannot have both `1` and `1.0` as keys since they are effectively identical for the hashmap – Giacomo Alzetta Nov 05 '18 at 14:37
  • I'd say, it's certainly not a problem. Worst thing that could happen: A few more hash collisions in a `Map` or `Set` containing instances of both classes. But you could also just add the hashcode of the class itself to the instances' hashcodes. – tobias_k Nov 05 '18 at 14:40

3 Answers3

1

I have come across a similar situation. Basically, the implementations (I had two) would look exactly alike.

If I had used just one class then the class name created confusion when used at the other place. So, I went ahead with two classes to improve readability.

Example: Hooks that are used pre and post initialization of something lead to creating two classes PreInit and PostInit. But, at that time, the requirement was to do the same thing at the pre and post init. But, in the very near future, this would change and each will have different logic.

Two different objects can have the same hash code and there is nothing wrong about that (as long as you take care of the equals)

See: two unequal objects with same hashcode

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
1

Yes, it's OK to have the same hashcode for different objects.
As you know hashcodes range restricted by int type in java. But the range of objects is not restricted. The situation where different objects have the same hashcode called collision.
To avoid errors related to it you should remember about the contract between hashcode and equals:
1) If two objects are equal, then they must have the same hash code.
2) If two objects have the same hash code, they may or may not be equal.
You can find more about it here

Pizza eu
  • 1,419
  • 1
  • 14
  • 27
1

Different objects giving the same hashCode() is for sure "okay". It is the nature of hashes to sometimes collide. A hash code maps a potentially infinite range onto a restricted range. Collisions are inevitable. Especially when thinking about objects of different types, it really doesn't matter too much whether someA and someB have equal or different hash codes!

But beyond that, the other answer is: your question implies a design problem. You shouldn't ask "is it ok for two interfaces to use the exact hash code". You should rather ask: "why did I end up with with two classes that share so much common aspects?!"

The real issue here is code quality: you duplicated fields, and probably code dealing with those fields. Most likely, the "better" approach would be refactor both classes, and push the common aspects into a distinct class, and then have your two classes use that common class!

GhostCat
  • 137,827
  • 25
  • 176
  • 248