Come sovrascrivere correttamente il metodo equals in Java?
sobes.tech AI
Risposta dell'AI
// Esempio di ridefinizione minima corretta di equals
class MyClass {
private int id;
private String name;
public MyClass(int id, String name) {
this.id = id;
this.name = name;
}
@Override // Annotazione obbligatoria
public boolean equals(Object o) {
// 1. Controllo di identità
if (this == o) return true;
// 2. Controllo di null e corrispondenza delle classi
// Usare getClass() per un controllo rigoroso
if (o == null || getClass() != o.getClass()) return false;
// 3. Cast
MyClass myClass = (MyClass) o;
// 4. Confronto dei campi significativi
return id == myClass.id &&
// Usare Objects.equals per confrontare gli oggetti (gestisce null)
Objects.equals(name, myClass.name);
}
}
Regole per una corretta ridefinizione di equals (secondo il contratto di Object.equals):
- Riflessività: Per ogni valore non nullo
x,x.equals(x)deve restituiretrue. - Simmetria: Per ogni
xeynon nulli,x.equals(y)deve restituiretruese e solo sey.equals(x)restituiscetrue. - Transitività: Per
x,y, eznon nulli, sex.equals(y)ey.equals(z)sonotrue, allorax.equals(z)deve esseretrue. - Coerenza: Per
xeynon nulli, molteplici chiamate ax.equals(y)devono restituire coerentementetrueofalse, fintanto che le informazioni usate per il confronto non cambiano. - Per ogni
xnon nullo,x.equals(null)deve restituirefalse.
Si consiglia di usare Objects.equals(obj1, obj2) per confrontare in modo sicuro gli oggetti, poiché gestisce correttamente null.
Sempre ridefinire hashCode() quando si ridefinisce equals(), in conformità con il contratto generale di Object.hashCode: se due oggetti sono uguali secondo equals(), i loro hashCode, restituiti da hashCode(), devono essere uguali. La condizione inversa non è richiesta. La mancata osservanza di questa regola può causare comportamenti errati delle collezioni basate su tabelle hash (ad esempio, HashMap, HashSet).
// Esempio di hashCode corrispondente per MyClass
class MyClass {
private int id;
private String name;
// ... costruttore e equals come sopra ...
@Override
public int hashCode() {
// Uso di Objects.hash per calcolare facilmente l'hash
return Objects.hash(id, name);
}
}
Può essere generato automaticamente con IDE (IntelliJ IDEA, Eclipse) i metodi equals e hashCode, che rappresenta una buona pratica.
Usa instanceof invece di getClass() solo se la classe fa parte di una gerarchia di ereditarietà e vuoi che oggetti di superclasse e sottoclasse siano considerati uguali se hanno lo stesso stato. Nella maggior parte dei casi, è preferibile usare getClass() per un controllo rigoroso.