Sobes.tech
Middle

Αναφέρετε τις συγκρούσεις στο HashMap.

sobes.tech AI

Απάντηση από AI

Μια σύγκρουση στο HashMap συμβαίνει όταν δύο διαφορετικά κλειδιά έχουν τον ίδιο κωδικό κατακερματισμού (hash code). Αυτό δεν οδηγεί σε απώλεια δεδομένων, αλλά επηρεάζει την απόδοση.

Κατά την εισαγωγή ενός στοιχείου:

  1. Καλείται η hashCode() της κλειδιού.
  2. Υπολογίζεται το ευρετήριο του κάδου στον πίνακα με βάση τον κωδικό κατακερματισμού.
  3. Αν ο κάδος είναι άδειος, το στοιχείο εισάγεται.
  4. Αν ο κάδος ήδη περιέχει στοιχεία, καλείται η equals() για κάθε στοιχείο στον κάδο με τη νέα κλειδί.
  5. Αν η equals() επιστρέψει true, η τιμή ενημερώνεται.
  6. Αν η equals() πάντα επιστρέφει false, προστίθεται ένα νέο στοιχείο στον κάδο.

Πριν από το Android 7.0 (Nougat), το HashMap χρησιμοποιούσε συνδεδεμένες λίστες για την επίλυση συγκρούσεων. Με πολλές συγκρούσεις σε έναν κάδο, η αναζήτηση στη λίστα γίνεται O(n), όπου n είναι ο αριθμός των στοιχείων στον κάδο.

Από το Android 7.0 και μετά, για κάδους με πολλές συγκρούσεις (όριο 8 στοιχείων), το HashMap μετατρέπει αυτόματα τη λίστα σε ένα κόμβο δέντρου κόκκινο-μαύρο (TreeNode). Η αναζήτηση στο δέντρο έχει πολυπλοκότητα O(log n), που βελτιώνει σημαντικά την απόδοση σε περιπτώσεις πολλών συγκρούσεων. Αν ο αριθμός των στοιχείων στον κάδο επιστρέψει κάτω από το όριο (6 στοιχεία), το δέντρο μετατρέπεται ξανά σε συνδεδεμένη λίστα.

Μια καλή υλοποίηση του hashCode() και equals() για προσαρμοσμένα αντικείμενα είναι το κλειδί για τη μείωση των συγκρούσεων και την αποτελεσματικότητα του HashMap.

Παράδειγμα:

@Override
public int hashCode() {
    // Παράδειγμα καλής υλοποίησης hashCode
    int result = 17;
    result = 31 * result + field1.hashCode();
    result = 31 * result + field2;
    return result;
}

@Override
public boolean equals(Object o) {
    // Παράδειγμα σωστής υλοποίησης 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);
}