Rozprávajte o kolíziách v HashMap.
sobes.tech AI
Odpoveď od AI
Kolízia v HashMap nastáva, keď dva rôzne kľúče majú rovnaký hash kód. To nevedie ku strate dát, ale ovplyvňuje výkon.
Pri vkladaní prvku:
- Zavolá sa
hashCode()kľúča. - Vypočíta sa index koša v poli na základe hash kódu.
- Ak je kôš prázdny, prvok sa vloží.
- Ak kôš už obsahuje prvky, pre každý prvok v koši sa volá
equals()s novým kľúčom. - Ak
equals()vrátitrue, hodnota sa aktualizuje. - Ak
equals()vždy vrátifalse, nový prvok sa pridá do koša.
Do Android 7.0 (Nougat), HashMap používala spojené zoznamy na riešenie kolízií. Pri veľkom počte kolízií v jednom koši sa vyhľadávanie v zozname stáva O(n), kde n je počet prvkov v koši.
Od Android 7.0, pre koše s veľkým počtom kolízií (práh 8 prvkov), HashMap automaticky konvertuje spojený zoznam na červenú-čiernu strom (TreeNode). Vyhľadávanie v strome má zložitosť O(log n), čo výrazne zlepšuje výkon pri veľkom počte kolízií. Ak počet prvkov v koši opäť klesne pod práh (6 prvkov), strom sa opäť konvertuje na spojený zoznam.
Dobrá implementácia hashCode() a equals() pre vlastné objekty je kľúčom k minimalizácii kolízií a zabezpečeniu efektívnosti HashMap.
Príklad:
@Override
public int hashCode() {
// Príklad dobrej implementácie hashCode
int result = 17;
result = 31 * result + field1.hashCode();
result = 31 * result + field2;
return result;
}
@Override
public boolean equals(Object o) {
// Príklad správnej implementácie equals
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyObject myObject = (MyObject) o;
return field2 == myObject.field2 &&
field1.equals(myObject.field1);
}