# 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 ```bash 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](../LICENSE).