2015-03-29 8 views
5
public class Person { 
    private String name, comment; 
    private int age; 

    public Person(String n, int a, String c) { 
     name = n; 
     age = a; 
     comment = c; 
    } 

    public boolean equals(Object o) { 
     if (!(o instanceof Person)) 
      return false; 
     Person p = (Person) o; 
     return age == p.age && name.equals(p.name); 
    } 
} 

Qual è la definizione appropriata del metodo hashCode nella classe Persona?cose da tenere a mente durante l'override hashCode

A. return super.hashCode();
B. return name.hashCode() + age * 7;
C. return name.hashCode() + comment.hashCode()/2;
D. return name.hashCode() + comment.hashCode()/2 - age * 3;

La risposta è B.

Qualcuno può spiegare perché C e D hanno torto?

+0

È possibile utilizzare uno di questi metodi hashcode (A potrebbe non dare buoni risultati), ma B è il più semplice. – JonasCz

+1

@JonasCz C e D sono errati perché non sono coerenti con gli uguali –

risposta

8

A, C e D, hashCode() potrebbe restituire un risultato diverso per 2 casi di cui Personequals() metodo restituisce true, cioè due Person s che sono uguali potrebbe restituire diversi codici hash.

Questo viola chiaramente contratto Object.hashCode() s':

se due oggetti sono uguali secondo il metodo equals (Object), quindi la chiamata al metodo hashCode su ciascuno dei due oggetti deve produrre lo stesso risultato intero.

per C e D, se due Person s avevano la stessa età e il nome, ma un commento diverso, equals() sarebbero tornati true, mentre hashCode() produrrebbe valori diversi.

A, come Person discende implicitamente dalla classe Object (cioè esso non si estende da qualsiasi superclasse esplicito), il risultato di super.hashCode() sarebbe uguali solo quando viene richiamata nella stessa istanza. Secondo Object.hashCode() documenti:

Per quanto ragionevolmente possibile, il metodo hashCode definito dalla classe Object non ritorno interi distinti per oggetti distinti. (Questo in genere viene implementato convertendo l'indirizzo interno dell'oggetto in un numero intero, ma questa tecnica di implementazione non è richiesta dal linguaggio di programmazione Java ™.)

Quindi, se tu avessi due diverse istanze della classe Person, entrambi con lo stesso nome, l'età e commentare, equals() sarebbero tornati true, mentre hashCode() sarebbe restituire valori diversi, violando hashCode() s' contratto.

In pratica, ciò significa che la classe Person non può essere la chiave di qualsiasi Map.

+1

Buona spiegazione! :) –

2

Dalla lettura superficiale. Sembra che B sia il migliore perché il metodo equal() tiene conto di queste due variabili (che è il nome e l'età).

4

Il metodo equals dice che gli oggetti sono uguali quando hanno lo stesso nome ed età. I commenti non influenzano l'uguaglianza qui.

Il contratto di uguale e hashCode richiede che 2 oggetti uguali abbiano lo stesso codice hash .

C e D possono violare questa regola perché gli oggetti con lo stesso nome ed età, ma i commenti differenti hanno come risultato diversi hashCode.

Problemi correlati