Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hashCode implementation for "equals any of some fields are equal"

I want objects of a particular class to be equal if one of their fields are equal. How can I write a consistent hashCode method for such a class?

(Disclaimer because I know this is not best practice: The class is a wrapper for another class and should be used for keys in Maps. It is intended that two different of these objects with one equal field would result in the same Map entry. Actually each of the fields would identify the underlying object on their own but I do not always have the same identifying field for two objects available. I cannot control and therefore change this "ambiguous" identification mechanism. Alternative solutions to tackle this are also welcome.)

Are there strategies for implementing hashCode() accordingly? I only know of implementations involving conjunctions (as with &&) in equals. How to make sure that hashCode() is the same if either of the fields is equal?

Here is the simplified equals method for which I would like to write a consistent hashCode() implementation:

public boolean equals(C other)
{
    return (field1 != null && field1.equals(other.field1))
            || (field2 != null && field2.equals(other.field2))
            || (field3 != null && field3.equals(other.field3));
}

EDIT: as per the input data, no cases like (1, 2, 3) equals (1, 6, 7) can occur. The objects are only produced such that some of the fields can be null, but not contradicting as in the example. Simply put in practise the only combinations equal to (1, 2, 3) should be (1, 2, 3), (1, null, null), (null, 2, null), (1, 2, null) and so forth. I acknowledge that this approach is not particularly robust.

like image 687
JayK Avatar asked Feb 25 '15 12:02

JayK


2 Answers

You can't use any fields to implement the hashCode because the field aren't equals all the time.

Your hashCode method needs to return the same value for equals objects all the time. As only one field needs to be equal in your equals method, and it isn't always the same, your only option is to return a constant in your hashCode method.

The implementation is inefficient but it is valid and consistent with equals.

The implementation could be:

public int hashCode() {
    return 0;
}
like image 52
David SN Avatar answered Sep 25 '22 12:09

David SN


You don't usually implement equals() and hashCode() using just one field of your object class. Everyone will probably advise you against it. The general practice is to ensure that you compare all the fields and ensure that they are all equal in order to call .equals(). hashCode() uses .equals() in order to hash those objects. However, if you can control what you are doing, you can simply use the hashCode() of a particular field of your object and override .equals() and .hashCode() based on that (but again, not advisable).

like image 23
ha9u63ar Avatar answered Sep 24 '22 12:09

ha9u63ar