2011-07-29 22 views
8
public class Contact 
{ 
    int i; 
    String name; 
    public Contact(int iVal, String nameVal) 
    { 
     i = iVal; 
     name = nameVal; 
    } 
} 

public class MultiMap 
{ 
    public static void main (String args[]) 
    { 
     java.util.HashMap m = new java.util.HashMap(); 
       Contact m1 = new Contact(1, "name"); 
     Contact m2 = new Contact(1, "name"); 
     m.put(m1, "first"); 
     m.put(m2, "second"); 
     System.out.println(m.get(m1)); 
     System.out.println(m.get(m2)); 
    } 
} 

de salida es:objetos como llaves mapa sin Hashcode y es igual a

first 
second 

¿Cómo se comporta este método "get"? Como tanto m1 como M2 tienen los mismos valores y no he reemplazado a hashcode(), ¿se llamará al método equals() de la clase Object?

¿Es esto correcto?

  1. No existe un método hashCode lo que no hay manera para que la JVM para ver si los objetos M1 y M2 contienen valores diferentes
  2. No hay igual método anulado de manera objeto es igual de clase() se invoca y que ambos objetos son diferentes, el código anterior funciona bien sin m2 reemplazando el valor de m1.

Respuesta

8

Cuando los métodos hashCode() y equals(Object o) no son eliminados por su clase, Java simplemente utiliza la referencia real al objeto en la memoria para calcular los valores (es decir. Comprobar si es la misma instancia de la clase). Es por eso que todavía obtienes ambos resultados.

0

Aquí en Contact clase que no aplicaran el hashcode() y equals() funciones.

Cuando HashMap llama a este método buscará estos métodos en la clase principal que es Object en este caso.

En este caso, se evalúa la ubicación del objeto en el Heap en lugar de los valores.

p. Ej. Para dos objetos o1 y o2

o1.equals(o2) == true sólo cuando o1 == o2

hashCode() es un método de clase Object. El código hash es una representación entera de un objeto por JVM. El código Hash es generado por el sistema y JVM toma la dirección del objeto como base (semilla) para generar el código hash. Los códigos hash generados no necesitan ser los mismos para diferentes tiempos de ejecución.

0

Sí, esto es correcto. Cualquier objeto java que no defina sus propios métodos equals y hashcode heredará los métodos equals y hascode predeterminados en java.lang.Object. Estas implementaciones predeterminadas se basan en la igualdad de referencia de objeto y no en la igualdad lógica. Como ha llamado get con la misma referencia de objeto, el objeto puede devolverse desde el mapa.

Aquí hay un ejemplo que ilustra esto aún más.

java.util.HashMap m = new java.util.HashMap(); 
Contact m1 = new Contact(1, "name"); 
Contact m2 = new Contact(1, "name"); 
m.put(m1, "first"); 
m.put(m2, "second"); 
System.out.println(m.get(m1));//first 
System.out.println(m.get(m2));//second 
System.out.println(m.get(new Contact(1, "name"));//null - since the new object has a different object reference. 
0

Aunque m1 y m2 tienen los mismos valores, son referencias de objetos diferentes.

Esto es correcto: no hay un método hashCode lo que no hay manera para que la JVM para ver si los objetos M1 y M2 contienen valores diferentes -> Por lo tanto, se utiliza el método hasCode de la clase Object() para calcular el valor hashCode para ejecutar el get(), que devuelve diferentes valores hash (obvio).

El segundo punto es también correcta: Como no ha implementado sus propios iguales(), tendrá en cuenta los iguales del objeto() que devuelve cierto sólo cuando un objeto se compara a sí mismo.

2

Utilizará el método equals y hashcode de la clase de objeto para encontrar el valor (ya que Contact no sobrepasa los métodos equals y hashcode), entonces sí.

  1. Sí, Java siempre verá dos objetos de contacto son diferentes, ya que utilizará referencia a un objeto de comparar cuando se utiliza el método equals en el objeto
  2. Sí, como dos objetos de contacto han de referencias.
3

Todos los objetos tienen hashCode() y es igual a(). Cuando no se reemplazan, se usan las implementaciones predeterminadas. El comportamiento predeterminado es tratar todos los objetos como diferentes, a menos que sean el mismo objeto.

Para comparar, IdentityHashMap siempre hace esto incluso si ha anulado su hashCode y es igual.

0

Por defecto, la clase de objeto anula el método hash y el método igual. Esta es la razón por la que obtienes el resultado deseado.

Si no anula el método equals y hashcode, JVM lo verifica detrás de la escena. Como m1 y m2 ambas son instancias de objetos diferentes, el método igual siempre devuelve falso. es decir:

1. Para iguales:

m1.equals (m2) // devuelve falso, porque ambos son diferentes instancias.

2. Para hashCode: // ver el código fuente interna HashMap.java

HashMap utiliza internamente para un refrito de la llave antes de poner en Hashmap. Ver abajo.

[![Source code of put method][1]][1] 
public V put(K key, V value) { 
    return putVal(hash(key), key, value, false, true); 
} 

para la repetición, Hashmap tiene su propio método de hash estática:

[![Source code of hash method][1]][1] 
static final int hash(Object key) { 
     int h; 
     return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
    } 

Internamente, ambos iguales y método hashCode trabajo de esta manera, es por eso que se obtiene tanto los valores almacenados en el HashMap .

Espero que esto ayude :)

Cuestiones relacionadas