Best Practice: quale può essere l'implementazione del metodo hashCode () se il campo personalizzato utilizzato nel metodo equals () è null?

1

Qual è la prassi migliore per restituire un valore per il metodo hashCode () se il campo personalizzato utilizzato in equals è nullo?

Ho una situazione in cui l'override di equals () è implementato utilizzando i campi personalizzati. Di solito si consiglia di sovrascrivere hashCode () usando i campi personalizzati usati in equals (). Ma se tutti i campi personalizzati usati in equals () sono nulli, quale sarebbe l'implementazione migliore per hashCode ()?

Esempio:

class Person {
    private String firstName;
    private String lastName;        
    public String getFirstName() {
        return firstName;
    }        
    public String getLastName() {
        return lastName;
    }
    @Override
    public boolean equals(Object object) {
        boolean result = false;
        if (object == null || object.getClass() != getClass()) {
            result = false;
        } else {
            Person person = (Person) object;
            if (this.firstName == person.getFirstName()
                && this.lastName == tiger.getLastName()) {
                result = true;
            }
        }
        return result;
    }        
    @Override
    public int hashCode() {
        int hash = 3;
        if(this.firstName == null || this.lastName == null) {
            // <b>What is the best practice here, </b>
            // <b>is return super.hashCode() better ?</b>
        }        
        hash = 7 * hash + this.firstName.hashCode();
        hash = 7 * hash + this.lastName.hashCode();
        return hash;
    }
}
  1. è richiesto per verificare null in hashCode ()?
  2. Se sì, cosa deve essere restituito se i valori personalizzati sono nulli?
posta goodspeed 04.06.2014 - 18:30
fonte

2 risposte

3

Se puoi garantire tramite il tuo codice che firstName e lastName non sono mai nulli, non c'è motivo di testarlo.

  • È possibile che questi valori siano impostati solo nel costruttore e che non ci sia un setter per esso. In tal caso, non sono mai nulli.

  • Oppure può darsi che tu abbia un setter che controlla null e popola una stringa vuota se viene passato un null in

In entrambi i casi, puoi garantire che i valori non siano sempre nulli e quindi non è necessario testarli.

Fare questo semplificherebbe drasticamente la quantità di pensiero necessaria per ragionare sul codice ed è probabilmente la strada giusta per implementare il codice.

Se fai consenti null nei valori, potresti semplicemente dire che l'hash del valore è 0. Basato sul tuo codice precedente:

@Override
public int hashCode() {
    int hash = 3;
    int firstHash = 0;
    int lastHash = 0;
    if(this.firstName != null) {
        firstHash = this.firstName.hashCode();
    }
    if(this.lastName != null) {
        lastHash = this.lastName.hashCode();
    }

    hash = 7 * hash + firstHash;
    hash = 7 * hash + lastHash;
    return hash;
}

hashCode non sta cercando di essere un hash crittograficamente sicuro - sta solo cercando di farlo in modo da non avere tutto il collisione in una HashMap e farlo degenerare in un elenco collegato.

Potresti essere interessato all'annotazione @NotNull che pone un requisito di tempo di compilazione su questo. Questo è stato implementato come parte di JSR 308 ... ma questo è qualcosa per Java 8.

    
risposta data 04.06.2014 - 19:27
fonte
1

Vorrei fare hashCode () come segue

public int hashCode () {   String str = this.firstName + "" + this.lastName;   return str.hashCode (); }

Ciò soddisfa i requisiti per hashCode () gli oggetti uguali hanno lo stesso hashCode ()

Non ha alcun problema nullo.

    
risposta data 04.06.2014 - 18:47
fonte

Leggi altre domande sui tag