equals() e hashCode()
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 42 di 87.
Quando confronti oggetti in Java, l'operatore == verifica se due riferimenti puntano alla stessa posizione di memoria. Per confrontare il contenuto effettivo degli oggetti, devi eseguire l'override del metodo equals().
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
}Il metodo equals() segue uno schema standard: prima verifica se si tratta dello stesso oggetto, poi controlla il tipo e infine confronta i campi pertinenti.
Ogni volta che esegui l’override di equals(), devi eseguire l’override anche di hashCode(). In Java, questa è una regola contrattuale: gli oggetti uguali devono avere lo stesso codice hash. Le collezioni basate su hash come HashMap e HashSet si basano su questa regola per funzionare correttamente.
@Override
public int hashCode() {
return Objects.hash(name, age);
}Il metodo di utilità Objects.hash() genera un codice hash a partire dagli stessi campi usati in equals(). Se due oggetti Person hanno lo stesso nome e la stessa età, saranno considerati uguali e produrranno codici hash identici, garantendo un comportamento coerente nelle collezioni.
Sfida
FacileCreiamo un sistema di gestione dei dati degli studenti che implementi correttamente l'uguaglianza tra oggetti. Creerai una classe Student in cui due studenti sono considerati uguali se hanno lo stesso ID studente e lo stesso nome, indipendentemente dal fatto che siano lo stesso oggetto in memoria.
Organizzerai il codice in due file:
Student.java: crea una classe che rappresenta uno studente con tre campi privati:studentId(String),name(String) egpa(double). Includi un costruttore per inizializzare tutti i campi e metodi getter per ciascun campo.Sovrascrivi il metodo
equals()in modo che due oggetti Student siano considerati uguali quando hanno lo stessostudentIdE lo stessoname. Segui lo schema standard: controlla che si tratti dello stesso riferimento, verifica che non sia null e che il tipo sia corretto, quindi confronta i campi pertinenti.Sovrascrivi il metodo
hashCode()usandoObjects.hash()con gli stessi campi usati inequals(). Ricorda di importarejava.util.Objectsall'inizio del file.Main.java: metti in pratica la tua classe Student confrontando gli oggetti studente. Riceverai sei input che rappresentano due studenti: l'ID, il nome e il GPA del primo studente, seguiti dall'ID, dal nome e dal GPA del secondo studente.Crea entrambi gli oggetti Student, quindi esegui tre confronti e stampa i risultati:
- Stampa
Same reference:seguito dal risultato del confronto dello studente con se stesso (dovrebbe essere sempre true) - Stampa
Content equality:seguito dal risultato del confronto tra il primo e il secondo studente (in base alla tua implementazione di equals) - Stampa
Hash codes match:seguito dal risultato del confronto tra gli hash code dei due studenti
- Stampa
Riceverai sei input: ID del primo studente (String), nome del primo studente (String), GPA del primo studente (double), ID del secondo studente (String), nome del secondo studente (String) e GPA del secondo studente (double).
Nota che quando due studenti hanno ID e nomi corrispondenti, sia equals() restituisce true SIA i loro hash code coincidono. Questo è il contratto che devi rispettare!
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leggi i dati del primo studente
String id1 = scanner.nextLine();
String name1 = scanner.nextLine();
double gpa1 = scanner.nextDouble();
scanner.nextLine(); // consuma il carattere di nuova riga
// Leggi i dati del secondo studente
String id2 = scanner.nextLine();
String name2 = scanner.nextLine();
double gpa2 = scanner.nextDouble();
// TODO: Crea due oggetti Student usando i dati di input
// TODO: Stampa "Same reference: " seguito dall'indicazione se student1 è uguale a sé stesso
// TODO: Stampa "Content equality: " seguito dall'indicazione se student1 è uguale a student2
// TODO: Stampa "Hash codes match: " seguito dall'indicazione se entrambi gli studenti hanno lo stesso codice hash
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione a oggetti
File esterniIntroduzione alla programmazione a oggettiClassi e oggettiLa parola chiave thisMetodiCampi (attributi)Metodo costruttoreSovraccarico dei costruttoriRipasso - Calcolatrice semplice4Ereditarietà
Ereditarietà di base (extends)La parola chiave superSovrascrittura dei metodi (@Override)Concatenamento dei costruttoriLa classe ObjectEreditarietà singola e multilivelloPerché non esiste l'ereditarietà multipla delle classiRiepilogo: gerarchia dei dipendenti7Metodi speciali e classe Object
Metodo toString()equals() e hashCode()Metodo clone()compareTo() e ComparableInterfaccia ComparatorRiepilogo - Ordinamento personalizzato2Modificatori di accesso e incapsulamento
Panoramica dei livelli di accessoMetodi getter e setterNascondimento delle informazioniLa parola chiave finalRiepilogo - Gestore di conti bancari5Polimorfismo
Nozioni di base sull'overloading dei metodiOverride dei metodi (a runtime)Upcasting e downcastingL'operatore instanceofClassi e metodi astrattiRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàAggregazione vs composizioneClassi interne, annidate e anonimeEnum e metodi degli EnumRecord (Java 16+)Classi sealed (Java 17+)11Modelli di progettazione Parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern BuilderPattern ObserverPattern Strategy3Proprietà di classe e membri statici
Variabili di istanza e staticheMetodi staticiBlocchi staticiCostanti (static final)Riepilogo - Contatore e utility6Interfacce e classi astratte
Introduzione alle interfacceImplementazione delle interfacceImplementazione di più interfacceMetodi default e static nelle interfacceClassi astratte e interfacce a confrontoInterfacce funzionaliRiepilogo: sistema di pagamento9Tipi generici
Introduzione ai tipi genericiClassi genericheMetodi genericiParametri di tipo con limitiCaratteri jolly (?, extends, super)Riepilogo - Contenitore generico12Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern IteratorEsercitati da solo: Compilatore Java online