He estado trabajando con HashMap de Java últimamente y he tropezado con un comportamiento interesante. Actualmente lo estoy usando para almacenar objetos clave/valor con múltiples campos. Para ello he anulado hashCode() y equals() de la siguiente manera:Java HashMap con hash overridden hashCode() y equals() no devuelve datos
public final class TransitionState {
private String mStackSymbol;
private String mTransitionSymbol;
private int mState;
private static final int HASH_SEED = 7; //Should be prime
private static final int HASH_OFFSET = 31;
//Constructor and getter methods here
public boolean equals(TransitionState other) {
//Check that we aren't comparing against ourself
if (this == other) {
return true;
}
//Check that we are not comparing against null
if (other == null) {
return false;
}
//Check fields match
if ((mState == other.getState()) &&
(mTransitionSymbol.equals(other.getTransitionSymbol())) &&
(mStackSymbol.equals(other.getStackSymbol()))) {
return true;
} else {
return false;
}
}
public int hashCode() {
int intHash = HASH_SEED;
//Sum hash codes for individual fields for final hash code
intHash = (intHash * HASH_OFFSET) + mState;
intHash = (intHash * HASH_OFFSET) + (mTransitionSymbol == null ? 0 : mTransitionSymbol.hashCode());
intHash = (intHash * HASH_OFFSET) + (mStackSymbol == null ? 0 : mStackSymbol.hashCode());
return intHash;
}
}
Ahora, yo soy capaz de poner los artículos en el mapa sin problema. Recuperarlos, sin embargo, es otra historia. Cada vez que intento get() desde HashMap, se devuelve NULL. Escribí un código de prueba para iterar sobre el Mapa e imprimir valores, que es donde las cosas se vuelven confusas, ya que el hashCode() de mis objetos clave coincide con el que tengo en mi mapa y la igualdad con un valor conocido devuelve verdadero. Salida de ejemplo de la siguiente manera (véase el cuarto paso de la parte inferior de la tabla):
Transition Table:
State Symbol Stack Move
--------------------------
1, a, b, (1, pop) with key hashcode 212603 and value hashcode 117943
0, b, a, (0, pop) with key hashcode 211672 and value hashcode 117912
1, b, z, (1, push) with key hashcode 212658 and value hashcode 3459456
0, a, b, (0, pop) with key hashcode 211642 and value hashcode 117912
1, a, z, (0, push) with key hashcode 212627 and value hashcode 3459425
0, a, a, (0, push) with key hashcode 211641 and value hashcode 3459425
0, a, z, (0, push) with key hashcode 211666 and value hashcode 3459425
0, b, z, (1, push) with key hashcode 211697 and value hashcode 3459456
1, b, a, (1, pop) with key hashcode 212633 and value hashcode 117943
1, b, b, (1, push) with key hashcode 212634 and value hashcode 3459456
ababba
Transition from (0, a, z) with hashcode 211666
transition.equals(new TransitionState(0, "a", "z")) = true
HashMap containsKey() = false
Transition not found
false
Como se puede ver, los hashcodes los partidos clave con una entrada en el mapa, pero estoy siendo dicho que es que no existe. Intenté depurar en el método containsKey() de HashMap, que hace un get() que se marca para NULL. Entrar en el get() muestra que el ciclo solo se está ejecutando una vez antes de devolver NULL.
Entonces, ¿es este un problema de HashMap (probablemente no) o (más probable) qué podría estar haciendo mal? Gracias de antemano por su ayuda.
la razón perfecta por la cual '@ Overrides' siempre debe usarse. –
@matt b: estaba a punto de agregar que :) –
Dios mío, tienes razón. Estaba tan concentrado en la implementación que lo más simple me atrapó. Trabajado como un encanto. Gracias por su rápida respuesta. – phobos51594