Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b66uwsWr9B1ouyrzUh
1.8 KiB
1.8 KiB
equals-hashcode
Companion code for the ankurm.com post "equals() and hashCode() in Java: The Contract, Real Bugs and How Records Change It."
Module in java-core-examples, the Java-core series. There is no docs/ folder: the deeper material lives in the post itself.
Versions this was built and tested against
| Component | Version | Notes |
|---|---|---|
| JDK | 25.0.5+8 (Temurin, LTS) | Records (final since 16) generate equals/hashCode. |
| JUnit Jupiter | 5.11.0 | |
| Maven | 3.9.11 |
Quickstart
export JAVA_HOME=/path/to/jdk-25
mvn compile
scripts/run.sh MutableKeyDemo # one demo
scripts/run-all.sh # regenerate every file in output/
What's in here
| File | What it shows |
|---|---|
ContractDemo.java |
The five rules, each broken on purpose: symmetry (instanceof + extra field), transitivity (the "lenient" fix), consistency. |
MissingHashCodeDemo.java |
equals() without hashCode(); a constant hashCode() and the 2,002,999 equals() calls it costs for 2,000 lookups. |
MutableKeyDemo.java |
A key mutated after insertion: get returns null, remove fails, iteration still sees it. |
SymmetryDemo.java |
java.util.Date vs java.sql.Timestamp: the JDK breaks symmetry itself. |
RecordsDemo.java |
What records generate; array components, mutable lists, NaN and -0.0; overriding equals. |
EntityIdDemo.java |
The JPA entity trap simulated without a database (id null until "saved"). No Hibernate involved. |
HashCodeRecipeDemo.java |
What String, List, Set, Map, Objects.hash, Arrays.hashCode actually compute. |
EqualsHashCodeTest.java |
Pins every claim above as an assertion. |
output/01-08 |
Captured runs of everything above. |
License
MIT - see LICENSE.