Files

39 lines
1.8 KiB
Markdown

# 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).