2012-07-22 9 views
27

Ok, por lo que en Java 7 tenemosObjects.hash() vs Objects.hashCode(), clarifique

o.hashCode(); 
    Objects.hashCode(o); 

    Objects.hash(o); 

Los 2 primeros son más o menos lo mismo con la comprobación de punto nulo, pero lo que es último ?

Cuando se proporciona una única referencia de objeto, el valor devuelto es que no es igual al código hash de esa referencia de objeto.

¿Por qué es eso? Quiero decir, no necesitamos 3 métodos que hagan lo mismo, lo entiendo ... pero ¿por qué necesitamos Objects.hash()? ¿Cuándo elegirías usar uno frente a otro?

Respuesta

47

Consulte la documentación para hashCode y hash. hash toma Object... mientras que hashCode toma Object. El ejemplo dado es:

@Override public int hashCode() { 
    return Objects.hash(x, y, z); 
} 
  • Objects.hash(Object... values) debe usarse en casos cuando se desea un hash de una secuencia de objetos, por ejemplo, al definir su propio método hashCode y desea un hash simplemente codificado para múltiples valores que conforman la identidad de su objeto.
  • Objects.hashCode(Object o) se debe utilizar cuando desee el hash de un solo objeto, sin tirar si el objeto es nulo.
  • Object::hashCode() se debe usar cuando se desee el hash de un solo objeto, y arrojará una excepción si el objeto es nulo.

Tenga en cuenta que hash(o) y hashCode(o) no necesariamente devolverán lo mismo. Si lo hace por un solo objeto, probablemente debería usar hashCode.

+0

¿En qué situación 'hash (o)' y 'hashCode (o)' no devolverán el mismo valor? Los documentos para 'hash()' state 'Advertencia: cuando se proporciona una única referencia de objeto, el valor devuelto no es igual al código hash de esa referencia de objeto., Pero todavía estoy investigando para descubrir por qué. –

7

El hashCode() predeterminado de Object devuelve la dirección de memoria para el objeto. Así que si usted tiene la siguiente clase:

class Car { 
    String make; 
    String model; 
    int year; 

    public Car(String make, String model, int year) { 
     this.make = make; 
     this.model = model; 
     this.year = year; 
    } 
} 

luego crear dos objetos:

Car car1 = new Car("Toyota", "Corolla", 2010); 
Car car2 = new Car("Toyota", "Corolla", 2010); 

car1.hashCode() será diferente de car2.hashCode(), ya que cada objeto tendrá una dirección de memoria diferente .

¿Qué sucede si quiere que tanto car1 como car2 devuelvan el mismo código hash? En este caso, se debe reemplazar el método hashCode predeterminado Object() de la clase de coche de la siguiente manera:

@Override 
public int hashCode() { 
    Object[] x = {model, make, Integer.valueOf(year)}; 
    int hashArray = Arrays.hashCode(x); 
    return hashArray; 
} 

Esto hará que car1.hashCode() igual a car2.hashCode() porque el String.hashCode() calcula el hashCode basado en el contenido de la cadena, y el Integer.hashCode() devolverá el valor entero mismo.

En Java 7, puede usar Objects.hash (Object ... values). Así que nuestro nuevo coche hashCode() se verá de la siguiente manera:

@Override 
public int hashCode() { 
    return Objects.hash(model, make, year); 
} 

Objects.hash (del objeto ... valores) llamará Arrays.hashCode para usted.

Finalmente, Objects.hashCode (Object o) hará una comprobación nula. Devolverá 0 si el objeto es nulo. De lo contrario, llamará al método hashCode() de los objetos.

+0

El 'hashCode()' predeterminado no ha devuelto la dirección de memoria durante aproximadamente 20 años. No puede realmente. GC mueve objetos alrededor. La llamada dirección de memoria es la de un controlador irrevocable. – EJP

+0

Basado en el documento de Java https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode El hashCode "se implementa normalmente al convertir la dirección interna del objeto en un entero, pero esta técnica de implementación no es requerida por el lenguaje de programación Java ™ ". – ezzadeen

Cuestiones relacionadas