0

I used eclipse to generate the overriding of the Object's hashCode and equals methods and that generated a few questions regarding the hashCode overriding. Is the below hashCode() correct?

Questions:

-Why does eclipse generate two result = lines of code? I would think that adding the two results together is appropriate. Any ideas why they're separate assignments?

-Can the final int prime be any prime number?

-Should int result always be 1?

public class Overrider {
    private Long id;
    private String name;
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.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;
        Overrider other = (Overrider) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}
c12
  • 9,557
  • 48
  • 157
  • 253
  • possible duplicate of [Overriding equals and hashCode in Java](http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java) – Brian Roach Jul 17 '13 at 23:30
  • its not a duplicate, I want to know if what Eclipse has inserted is valid as its different than other examples I've seen – c12 Jul 17 '13 at 23:48
  • "_Any idea why they're separate assignments?_" Because readable code is much better than the garbage that results from jamming tons of logic into one line. – jahroy Jul 18 '13 at 00:06

3 Answers3

2

-Why does eclipse generate two result = lines of code? I would think that adding the two results together is appropriate. Any ideas why they're separate assignments?

Please remember that this is code that runs in eclipse to generate code. Therefore, there is a specific logic. It is much easier to generate one line per variable instead of one line for all.

Also, it makes the code much more readable... can you imagine combining those two statements into one?

return prime * (prime + ((id == null) ? 0 : id.hashCode()) ) + 
((name == null) ? 0 : name.hashCode());

I will not bother with simplifying that but it would become quite large and hideous if there were 10 class variables...

"Can the final int prime be any prime number?"

Have a look at: Why does Java's hashCode() in String use 31 as a multiplier? I am quoting from there, which quotes the Book "Effective Java"...

According to Joshua Bloch's Effective Java (a book that can't be recommended enough, and which I bought thanks to continual mentions on stackoverflow):

"The value 31 was chosen because it is an odd prime. If it were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional. A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance: 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically."

Community
  • 1
  • 1
Menelaos
  • 23,508
  • 18
  • 90
  • 155
2

-Why does eclipse generate two result = lines of code? I would think that adding the two results together is appropriate. Any ideas why they're separate assignments? Answer : You have fix prime number defined above 'final int prime = 31;'. Assume following cases

id.hashcode()=1 & name.hashcode()=2. Hashcode by addition = 32+33=65 Hashcode with eclipse Implementation= 994

id.hashcode()=2 & name.hashcode()=1. Hashcode by addition = 33+32=65 Hashcode with eclipse Implementation= 1024

Hashcode should be as unique as possible for better performance. With addition of results there is possibility of 2 different objects return same hashcode. Whereas with multiplication, there is very less chance to have duplicate hashcodes for different object.

-Can the final int prime be any prime number? It can be any number but it ensures that there will be very less possible duplicate hashcodes for different objects. E.g 31 above represents that even if difference of 1 in id.hashcodes of 2 different objects will ensure that actual hashcodes of these 2 objects will differ by atleast 31. S

-Should int result always be 1? It can be anything. It's just it should be non-zero and should avoid complexity in calculations to make it work fast.

2

Looks fine to me.

"Why does eclipse generate two result = lines of code?"

I'm guessing the reason is readability. It looks like you are multiplying the first result + the hash of the second field by the prime again, not just adding the two lines together. The generated code looks a lot better than:

result = (prime * result + ((id == null) ? 0 : id.hashCode())) + 
         (prime * (prime * result + ((id == null) ? 0 : id.hashCode())) + 
         ((name == null) ? 0 : name.hashCode())); 

"Can the final int prime be any prime number?"

Yep, but the higher the better. A higher number reduces the likelihood of a collision. In most cases 31 should be more than sufficient.

"Should int result always be 1?"

Assuming you mean "Should int result always be initialized to 1":

No, it just needs to be some constant that isn't 0.

zcotter
  • 207
  • 1
  • 8