Equal hashes don't mean equal objects
String.hashCode is s[0]*31^(n-1) + ... + s[n-1]: 65*31+97 = 66*31+66 = 2112. Use Double.compare in equals, not ==.
Every class inherits toString, equals and hashCode from Object. Override toString to get readable output, and override equals and hashCode together, following their contract, whenever two different objects should count as "the same value", because HashMap, HashSet and most of the collections library depend on it.
Change the code and press Run (Ctrl+Enter). Try to predict the output first, then break it on purpose and read the error. Your edits are saved and match the lesson page.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a final class Money with long paise and String currency, plus correct equals, hashCode and toString. Show that two equal amounts are equals and that a HashSet keeps only one.
Write an equals for a class Book(String isbn, String title) where two books are equal if their ISBNs are equal (the title may be null). Show that the null title causes no exception.
Show the symmetry trap: a class CaseInsensitive wrapping a String whose equals also accepts plain Strings ignoring case. Print ci.equals("HELLO") and "HELLO".equals(ci) and explain the result.
Explain it without notes
What do the default toString, equals and hashCode in Object do?
State the five rules of the equals contract.
State the hashCode contract and explain exactly what goes wrong in a HashSet if you override equals without hashCode.
Why is equals(Point p) a bug, and how does @Override help?
Why shouldn't you mutate an object while it's a key in a HashMap?
Expected output
"Aa".hashCode() = 2112
"BB".hashCode() = 2112
equal? false
Double.compare(0.0, -0.0) = 1
0.0 == -0.0 is true
NaN == NaN is false
Double.compare(NaN, NaN) = 0