0

I've never had occasion to write a hashcode function in Java but now I have a need to do so. How do I go about it?

It's for an ArrayList and each element contains 5 Strings and nothing else.

I found an example for an ArrayList that contains 2 string and it's very simple:

return 31 * lastName.hashCode() + firstName.hashCode();

Can I get away with something equally simple, namely:

return 31 * field1.hashcode() + field2.hashcode() + field3.hashcode() + field4.hashcode() + field5.hashcode();

Or does a hashcode() method have further requirements?

I found another StackOverflow discussion of hashcode() here: Best implementation for hashCode method

From that, I imitated one of the answers and came up with this:

return Objects.hash(this.mClientCode, this.mOrderNumber, this.mOrderDate, this.mTicketsSold, this.mSellerName);

Is that better than the first one I suggested? Why?

Since hashcode() and equals() should apparently always get changed at the same time, this is my equals():

   public boolean equals(Object o) {

    if (!(o instanceof SalesItem)) {
        return false;
    }

    SalesItem n = (SalesItem) o;

    return n.mClientCode.equals(mClientCode) && n.mOrderNumber.equals(mOrderNumber) &&
            n.mOrderDate.equals(mOrderDate) && n.mTicketsSold.equals(mTicketsSold) &&
            n.mSellerName.equals(mSellerName);
}

Does that look okay?

2 Answers 2

1

Your equals is almost right. If none of those values can be null, its good. If they can be, then you need to add null checks as well- if((n.lastName!= null && n.lastName.equals(lastname)) || (n.lastName == null && lastname == null)) and repeat for the others.

For the hash- what you want is the has to be as randomly distributed as possible and unique for the values you would consider unique. Its hard for us to tell you a good hash algorithm because we don't know how your data structure is used. For example, if there's only 4 sellers, you'd want that field to be a very small factor in the hash, if a factor at all.

Is this a representation of a database row? It looks like one. Because if it is, the rowId or a UUID for the row would be the best thing to hash.

Sign up to request clarification or add additional context in comments.

13 Comments

Objects.equals is typically preferable to complicated inline comparisons.
@chrylis Objects.equal(lastname, n.lastname) is equivalent to lastname.equals(n.lastname), but requires an additional function call with no additional clarity and actually more wordy, and doesn't allow you to control whether to accept nulls. I wouldn't reject a code review that did it, but I find there's between 0 and slightly negative value in adding it
Either nulls should be permitted at this class level or they shouldn't; in the case where they are, you have to check them, and Objects.equals does that inline for you.
@chrylis But if nulls aren't allowed, then I don't want the performance hit of checking them. Which adds up, especially if you're called in a loop- there's a reason why many IDEs ask if you want to add the null checks when generating an equals function. And quite truthfully- I have no idea if Objects.equals checks of not. I'd need to look up how it handles nulls (I assume you're right, but if I was reading it in code I'd need to check the docs). Which is another reason not to use it- I'd rather have it explicit.
@Gabe Sechan Yes, this ArrayList imitates a MySQL table. I've defined the table so that the primary key is the combination of ClientCode and OrderNumber and prohibited nulls in all five columns of the table. However, this ArrayList is used in an Android app that is going to insert, update, and delete the rows that go into the table. I think I am precluding insert and update logic inserting any nulls into the ArrayList and table (or changing existing non-nulls to nulls) so any nulls that get into the ArrayList are going to be due to sloppy coding on my part. ;-)
|
0

You can also use the HashCodeBuilder in the org.apache.commons.lang3 library.

Here is the documentation and an example:
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/HashCodeBuilder.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.