Πώς υπερισχύει σωστά η μέθοδος equals στη Java;
sobes.tech AI
Απάντηση από AI
// Παράδειγμα ελάχιστης σωστής επαναπροσδιορισμού του equals
class MyClass {
private int id;
private String name;
public MyClass(int id, String name) {
this.id = id;
this.name = name;
}
@Override // Υποχρεωτική σημείωση
public boolean equals(Object o) {
// 1. Έλεγχος ταυτότητας
if (this == o) return true;
// 2. Έλεγχος null και αντιστοιχία κλάσεων
// Χρησιμοποιούμε getClass() για αυστηρό έλεγχο
if (o == null || getClass() != o.getClass()) return false;
// 3. Μετατροπή τύπου
MyClass myClass = (MyClass) o;
// 4. Σύγκριση σημαντικών πεδίων
return id == myClass.id &&
// Χρησιμοποιούμε Objects.equals για σύγκριση αντικειμένων (λαμβάνει υπόψη null)
Objects.equals(name, myClass.name);
}
}
Κανόνες για σωστό επαναπροσδιορισμό του equals (σύμφωνα με τη σύμβαση του Object.equals):
- Αντανάκλαση: Για κάθε μη null
x, τοx.equals(x)πρέπει να επιστρέφειtrue. - Συμμετρία: Για κάθε μη null
xκαιy, τοx.equals(y)πρέπει να επιστρέφειtrueαν και μόνο αν τοy.equals(x)επιστρέφειtrue. - Μεταβατικότητα: Για κάθε μη null
x,y, καιz, αν τοx.equals(y)και τοy.equals(z)είναιtrue, τότε τοx.equals(z)πρέπει να είναιtrue. - Συνεπτικότητα: Για κάθε μη null
xκαιy, πολλαπλές κλήσεις τουx.equals(y)πρέπει να επιστρέφουν το ίδιο αποτέλεσμα, όσο δεν αλλάζουν οι πληροφορίες που χρησιμοποιούνται για τη σύγκριση. - Για κάθε μη null
x, τοx.equals(null)πρέπει να επιστρέφειfalse.
Συνιστάται η χρήση Objects.equals(obj1, obj2) για ασφαλή σύγκριση αντικειμένων, καθώς χειρίζεται σωστά το null.
Πάντα να επαναπροσδιορίζετε το hashCode() όταν επαναπροσδιορίζετε το equals(), σύμφωνα με τη γενική σύμβαση του Object.hashCode: αν δύο αντικείμενα είναι ίσα σύμφωνα με το equals(), τα hash codes τους, που επιστρέφονται από το hashCode(), πρέπει να είναι ίδια. Η αντίστροφη δεν απαιτείται. Η μη τήρηση αυτής της αρχής μπορεί να οδηγήσει σε λανθασμένη λειτουργία συλλογών που βασίζονται σε πίνακες κατακερματισμού (π.χ. HashMap, HashSet).
// Παράδειγμα κατάλληλου hashCode για MyClass
class MyClass {
private int id;
private String name;
// ... κατασκευαστής και equals όπως παραπάνω ...
@Override
public int hashCode() {
// Χρήση Objects.hash για εύκολη υπολογισμό του hash
return Objects.hash(id, name);
}
}
Μπορείτε να δημιουργήσετε αυτόματα τις μεθόδους equals και hashCode χρησιμοποιώντας IDEs (IntelliJ IDEA, Eclipse), κάτι που αποτελεί καλή πρακτική.
Χρησιμοποιήστε instanceof αντί για getClass() μόνο αν η κλάση αποτελεί μέρος ιεραρχίας κληρονομικότητας και θέλετε τα αντικείμενα της υπερκλάσης και της υποκλάσης να θεωρούνται ίσα αν έχουν την ίδια κατάσταση. Στις περισσότερες περιπτώσεις, προτιμάται η χρήση getClass() για αυστηρό έλεγχο.