Unapo-override equals() ili kufafanua usawa wa kimantiki, lazima pia u-override hashCode() — kwa sababu mikusanyiko inayotegemea hash (HashMap, ) inategemea mkataba kwamba . Kuvunja hili husababisha bugs dakika, ngumu kupata.
HashSet// by default, equals() compares IDENTITY (same object?), hashCode() is based on memory address
Person p1 = new Person("Ann", 30);
Person p2 = new Person("Ann", 30);
p1.equals(p2); // false by default — different objects, even with same data
Bila ku-override, objects mbili zenye maudhui yanayofanana ni "si sawa" — kwa kawaida si unachotaka kwa value objects.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person p = (Person) o;
return age == p.age && Objects.equals(name, p.name); // compare by CONTENT
}
@Override
public int hashCode() {
return Objects.hash(name, age); // MUST be consistent with equals()
}
Mkataba: kama a.equals(b) ni kweli, basi a.hashCode() == b.hashCode() LAZIMA iwe kweli.
Person p1 = new Person("Ann", 30);
Person p2 = new Person("Ann", 30); // equal by our equals()
Set<Person> set = new HashSet<>();
set.add(p1);
set.contains(p2); // ❌ likely FALSE — even though p1.equals(p2)!
Kwa nini? HashMap/HashSet kwanza hutumia hashCode() kupata bucket sahihi, kisha equals() ndani yake. Kwa hashCode() chaguo-msingi (inayotegemea identity), p1 na p2 huangukia katika buckets tofauti, kwa hivyo contains hailinganishi hata — set hudhani ni tofauti. Hii huzalisha bugs zinazochanganya: nakala kwenye Set, kushindwa kwa map lookups, n.k.
1. equal objects → equal hash codes (REQUIRED for correctness)
2. unequal objects MAY have the same hash (collisions are allowed)
3. hashCode() must be consistent (same object → same code, unchanged)
4. equals() must be reflexive, symmetric, transitive, consistent
record Person(String name, int age) {} // records auto-generate equals/hashCode/toString!
Java records (na IDE generation / Lombok) huzalisha equals/hashCode sahihi, thabiti kwa ajili yako.
Mkataba wa equals/hashCode ni mojawapo ya kanuni muhimu zaidi za Java — na zinazovunjwa zaidi.
Ku-override equals() bila hashCode() huvunja mikusanyiko inayotegemea hash kwa njia ngumu ku-debug: objects unazozichukulia kuwa sawa hupotea katika HashMap/HashSet (kushindwa kwa lookups, nakala za uzushi) kwa sababu zina hash kwenye buckets tofauti.
Kwa kuwa mikusanyiko hii imeenea, kila value-type class inayotumika kama key au set element lazima i-override zote mbili kwa uthabiti.
Kuelewa kwa nini (utaratibu wa bucket-kisha-equals wa lookup) — na kutumia records au msimbo uliozalishwa kuipata sahihi — ni muhimu kwa tabia sahihi na ni mada ya mahojiano ya kawaida inayofunua uelewa wa kweli wa jinsi mikusanyiko ya Java inavyofanya kazi.