murat8505 / projectlombok

Automatically exported from code.google.com/p/projectlombok
0 stars 1 forks source link

The generated equals and hashCode methods disagree #821

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Consider the 'StringWrapper' class below
2. Instantiate two instances of StringWrapper: new StringWrapper ("") and new 
StringWrapper () or new StringWrapper (null)
3. As expected, the equals method correctly determines that the instance with 
an empty string does not equal the one(s) with null
4. The hashCode method, however does not agree with the above and will generate 
'59' for all 3 mentioned instances

What is the expected output? 
new StringWrapper ("").hashCode() != new StringWrapper ().hashCode()
new StringWrapper ("").hashCode() != new StringWrapper (null).hashCode()

What do you see instead?
new StringWrapper ("").hashCode() == new StringWrapper ().hashCode()
new StringWrapper ("").hashCode() == new StringWrapper (null).hashCode()

What version of the product are you using? On what operating system?
Lombok-1.16.2 on Windows JDK 1.8_u45

According to 
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode():
* If two objects are equal according to the equals(Object) method, then calling 
the hashCode method on each of the two objects must produce the same integer 
result.
* It is not required that if two objects are unequal according to the 
equals(java.lang.Object) method, then calling the hashCode method on each of 
the two objects must produce distinct integer results. However, the programmer 
should be aware that producing distinct integer results for unequal objects may 
improve the performance of hash tables.

@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class StringWrapper {
    @Getter String string;
}

Original issue reported on code.google.com by copo...@gmail.com on 4 Jun 2015 at 11:17

GoogleCodeExporter commented 9 years ago
It's not a bug, though it might be worth changing. See an analogous discussion 
at
https://github.com/google/guava/issues/2037

Note also that such things are pretty common, e.g., the hashcodes of all these 
three strings equal 3587: "ps", "qT", "r5". And there are 560 such 3-way 
collisions among alphanumeric strings of length 2.

PS: You're wrong concerning `new StringWrapper()` and `new StringWrapper(null)` 
as they ARE equal (not "==", just "equals").

Original comment by Maaarti...@gmail.com on 6 Jun 2015 at 10:14

GoogleCodeExporter commented 9 years ago
I should have been more clear:
1- Yes, it's not a requirement, but more of a recommendation (for improved hash 
table performance)
2- In #2 above, I have an OR between 'new StringWrapper ()' and 'new 
StringWrapper(null)' meaning either one. I didn't mean the two shouldn't be 
equal. I meant 'new StringWrapper("")' should not be equal to either of the two 
(which are equal to each other).

Original comment by copo...@gmail.com on 6 Jun 2015 at 5:48