HashMap con anulación igual y hashCode no funciona

Lo siento... sobre esta pregunta tonta/estúpida, chicos:

Por qué no equals() y hashCode() ¿siendo aplicado?

Actualmente solo están funcionando como esperaba para HashSet.

ACTUALIZACIÓN

INCLUSO el valor de clave 5 se repite pero no llama a equals y hashCode.

Quiero aplicarlo también en Value.

Al igual que HashSet llama a equal y hashCode en este ejemplo, ¿por qué hashMap no se llama equals y hashCode incluso si es clave?

ACTUALIZACIÓN2 - RESPUESTA

Se llamaría a la clave de HashMap (clase-> HashCode, es igual). Gracias a todos. Estaba un poco confundido con esto. :)

    public class Employee {

        int id;
        String name; 
        int phone;

        public Employee(int id, String name, int phone) {
            this.id = id;
            this.name = name;
            this.phone = phone;
        }    
    // Getter Setter

        @Override
        public boolean equals(Object obj) {

            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Employee other = (Employee) obj;
            System.out.println("Employee -  equals" + other.getPhone());
            if (this.id != other.id) {
                return false;
            }
            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
                return false;
            }
            if (this.phone != other.phone) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            System.out.println("Employee -  hashCode" );
            int hash = 3;
            hash = 67 * hash + this.id;
            hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
            hash = 67 * hash + this.phone;
            return hash;
        }
    }

____________________________________________________________________________________

public class MapClass {

    public static void main(String[] args) {
        Map<Integer,Employee> map = new HashMap<Integer,Employee>();
        map.put(1, new Employee(1, "emp", 981));
        map.put(2, new Employee(2, "emp2", 982));
        map.put(3, new Employee(3, "emp3", 983));
        map.put(4, new Employee(4, "emp4", 984));
        map.put(5, new Employee(4, "emp4", 984));
       **//UPDATE**
        map.put(5, new Employee(4, "emp4", 984));            

        System.out.println("Finish Map" + map.size());
        Set<Employee> set = new HashSet<Employee>();

        set.add(new Employee(1, "emp", 981));
        set.add(new Employee(2, "emp2", 982));
        set.add(new Employee(2, "emp2", 982));
        set.add(new Employee(3, "emp3", 983));
        set.add(new Employee(4, "emp4", 984));
        set.add(new Employee(4, "emp4", 984));

        System.out.println(set.size());
    }
}

LA SALIDA ES

Finish Map5
Employee -  hashCode
Employee -  hashCode
Employee -  hashCode
Employee -  equals982
Employee -  equals982
Employee -  hashCode
Employee -  hashCode
Employee -  hashCode
Employee -  equals984
Employee -  equals984
4

preguntado el 22 de mayo de 12 a las 13:05

¿Cuál es el problema exactamente? Recuerde que en HashMap, las claves se codifican, no el valor:

¿Cómo llamaría a hascode & equals para hashMap?

El Mapa llama a los métodos equals y hashCode, y lo está haciendo, ¡para la clave Integer! Si desea que el mapa verifique el código hash del empleado y/o sea igual, entonces el empleado debe ser la clave, no el valor. -

por qué no se llama a hashMap (equals & hascode) incluso si se repite for key. -

¡Me alegro de que lo hayas resuelto! 1+ -

4 Respuestas

INCLUSO el valor de clave 5 se repite pero no llama a equals y hashCode

Sí, llama a hashCode, en la clave, Integer.

Quiero aplicarlo también en Value

Dosis de realidad: Java HashMaps no funciona de esa manera. Verifican la clave solo en busca de duplicados, no el valor, y así es como debería ser.

Si desea que el hash del empleado se verifique en el mapa, entonces debe: ser la clave Período.

Otra posible solución es descargar uno de los multimapas que hay disponibles.

Editar para ver que está llamando a hashCode y es igual, cambie el tipo de clave de su mapa a algo así:

class MyInt {
   private Integer i;

   public MyInt(Integer i) {
      this.i = i;
   }

   public Integer getI() {
      return i;
   }

   @Override
   public int hashCode() {
      System.out.println("MyInt HashCode: " + i.hashCode());
     return i.hashCode();
   }

   @Override
   public boolean equals(Object obj) {
      System.out.printf("MyInt equals: [%s, %s]%n", i, obj);
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      MyInt other = (MyInt) obj;
      if (i == null) {
         if (other.i != null)
            return false;
      } else if (!i.equals(other.i))
         return false;
      return true;
   }

   @Override
   public String toString() {
      return i.toString();
   }

}

Luego llene su Mapa así:

   Map<MyInt,Employee> map = new HashMap<MyInt,Employee>();
   map.put(new MyInt(1), new Employee(1, "emp", 981));
   map.put(new MyInt(2), new Employee(2, "emp2", 982));
   map.put(new MyInt(3), new Employee(3, "emp3", 983));
   map.put(new MyInt(4), new Employee(4, "emp4", 984));
   map.put(new MyInt(5), new Employee(4, "emp4", 984));
   map.put(new MyInt(5), new Employee(4, "emp4", 984));

y verás:

MyInt HashCode: 1
MyInt HashCode: 2
MyInt HashCode: 3
MyInt HashCode: 4
MyInt HashCode: 5
MyInt HashCode: 5
MyInt equals: [5, 5]

contestado el 22 de mayo de 12 a las 14:05

@Ravi: Si el empleado fuera el clave del HashMap, verá que se llama al método hashCode. Vea mi edición anterior para ver cómo HashMap llama a hashCode y es igual. - Aerodeslizador lleno de anguilas

Gracias, entendí que se llamaría a la clave de HashMap (clase-> código hash). - RevenP

HashMap usa las claves como índice, no los valores. (Eso es hashCode(), y tal vez se llama a equals() en la clase Integer en su código anterior)

contestado el 22 de mayo de 12 a las 13:05

HashMap usa equals/hashCode del valor de la clave (en su caso, Integer). Creo que eso es lo que estás preguntando, ¿verdad?

La razón por la que tiene duplicados en su mapa es que está usando una nueva clave para el mismo empleado.

  map.put(4, new Employee(4, "emp4", 345));
  map.put(5, new Employee(4, "emp4", 345));  // You are using 5 as the key
                                             // for the "same" object you did 
                                             // in the previous line

Si hicieras algo como

  // in main
  addEmployee(new Employee(4, "emp4", 345));
  addEmployee(new Employee(4, "emp4", 345));

  private void addEmployee(Employee e)
  {
     map.put(e.getId(), e);
  }

Entonces no vería ningún duplicado en su colección.

contestado el 22 de mayo de 12 a las 14:05

quiero anular hashCode y Equals pero en HashMap 'Equals & hashCode' no se anula. Quiero aplicarlo también en Valor - RevenP

@Ravi: esto no tiene sentido. HashMap está funcionando bien. Simplemente no está entendiendo que la clave está siendo verificada. - Aerodeslizador lleno de anguilas

Solo quiero confirmar Como al igual que HashSet llama a equal y hashCode en este ejemplo, por qué no se llama a hashMap incluso si es por clave. - RevenP

eEl código que has proporcionado llamar al equals y hashCode por las llaves, pero las llaves son Integers, no Employees. - Luis Wassermann

Estás usando un HashMap<Integer, Employee>, parece que, por lo que el Integers será hash. Ya que las claves son 1,2,3,4,5, el tamaño de tu HashMap debería ser 5.

contestado el 22 de mayo de 12 a las 13:05

pero cuando lo ejecuta, el tamaño de la pantalla es 5 - RevenP

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.