Esta es una pregunta muy clásica en Java y a menudo se hace durante las entrevistas. De hecho, muchos libros o artículos han mencionado que debe sobrecargar los métodos hashcode () e igual () para realizar la búsqueda de claves personalizadas en HashMap. Sin embargo, parece que pocos artículos hablan sobre por qué necesita hacer esto y qué consecuencias serán causadas por no hacer esto, por lo que escribiré este artículo para explicarlo.
En primer lugar, ¿qué sucede si usamos directamente la siguiente clase de persona como clave y la almacenamos en hashmap?
Persona de clase pública {ID de cadena privada; Persona pública (ID de cadena) {this.id = id; }} import java.util.hashmap; public class Main {public static void main (string [] args) {hashmap <persona, string> map = new Hashmap <persona, string> (); map.put (nueva persona ("001"), "horthiningsea"); map.put (nueva persona ("002"), "linyin"); map.put (nueva persona ("003"), "Henrylin"); map.put (nueva persona ("003"), "hindesingseAly"); System.out.println (map.ToString ()); System.out.println (map.get (nueva persona ("001"))); System.out.println (map.get (nueva persona ("002"))); System.out.println (map.get (nueva persona ("003"))); }}Entonces, ¿cuál es el resultado de salida?
{Persona@6e4d4d5e = Henrylin, persona@275cea3 = findingsea, persona@15128ee5 = fintingsealy, persona@4513098 = Linyin} nullnullnullPodemos ver que hay dos problemas aquí:
1. Durante el proceso de adición, agregamos el par de valor clave de clave = nueva persona ("003") dos veces. En la expectativa, solo debería haber uno de esos pares de valor clave en HashMap. Debido a que la clave (esperada) es la misma, no debe agregarse repetidamente. El valor = "FindingseAly" agregó la segunda vez debería reemplazar el valor original = "Henrylin". Pero en la entrada, descubrimos que la situación esperada no ocurrió, pero hay dos pares de valor clave de valor = "findingsealy" y value = "Henrylin" en Hashmap, y sus valores clave siguen siendo diferentes, lo que obviamente es incorrecto.
2. Al obtener el valor del valor, usamos tres objetos de persona para buscar. Estos tres objetos son los mismos que los tres valores clave que acabamos de almacenar (en expectativas), pero la búsqueda es tres valores nulos, lo que obviamente también es incorrecto.
Entonces, el método correcto se ha descrito en muchos lugares. La clase de la persona se modifica directamente, sobrecarga los iguales y los métodos hashcode, y la clase de persona modificada es la siguiente:
Persona de clase pública {ID de cadena privada; Persona pública (ID de cadena) {this.id = id; } @Override public boolean iguales (objeto o) {if (this == o) return true; if (o == null || getClass ()! = o.getClass ()) return false; Persona persona = (persona) o; if (id! = null? devolver verdadero; } @Override public int hashcode () {return id! = NULL? id.hashcode (): 0; }}Luego, cuando reexpresamos el procedimiento de inspección anterior, los resultados son los siguientes:
{Persona@ba31 = findessea, persona@ba32 = Linyin, persona@ba33 = findingsealy} fintingSealinyInFindingSeLylyComo se puede ver, se han corregido todos los aspectos más destacados y errores señalados. Entonces, ¿por qué está sucediendo esto?
En hashmap, el orden de comparación de claves de búsqueda es:
1. Calcule el código hash del objeto para ver si existe en la tabla.
2. Verifique si el objeto en la ubicación del código hash correspondiente es igual al objeto actual.
Obviamente, el primer paso es usar el método hashcode (), y el segundo paso es usar el método igual (). Cuando no se realiza una sobrecarga, estos dos métodos de la clase de objeto se llamarán de forma predeterminada en estos dos pasos. En el objeto, el método de cálculo del código hash se calcula en función de la dirección del objeto. Las direcciones de objeto de las dos personas ("003") son diferentes, por lo que su código hash también es diferente. Naturalmente, hashmap no los tratará como la misma clave. Al mismo tiempo, en el valor predeterminado () del objeto, también se compara en función de la dirección del objeto. Naturalmente, una persona ("003") y otra persona ("003") no son iguales.
Después de comprender esto, es fácil descubrir por qué necesita sobrecargar tanto hashcode () como equivalente.
• La sobrecarga de hashcode () es obtener el mismo código hash para la misma clave, de modo que el hashmap se pueda colocar en la clave que especificamos.
• La sobrecarga de igual () es mostrar hashmap que el objeto actual y el objeto guardado en la clave son iguales, de modo que realmente podamos obtener el par de valor clave correspondiente a la clave.
Hay otro detalle. En la clase de la persona, el énfasis en el método hashcode () es:
@OverridePublic int hashcode () {return id! = NULL? id.hashcode (): 0;}El punto que puede estar perplejo aquí es: ¿por qué se puede utilizar el código hash de una variable de cadena de tipo como el valor del código hash de la clase de persona? ¿Son iguales los códigos hash de nueva persona (nueva cadena ("003")) y la nueva persona (nueva cadena ("003"))?
Echemos un vistazo a la salida del siguiente código:
System.out.println ("FindingSea" .HashCode ()); System.out.println ("Fintessea" .HashCode ()); System.out.println (new String ("FintesseA"). HashCode ()); System.Println (nuevo String ("Findingsea"). HashCode ()); 728795174728795174728795174728795174Puede ver que las salidas de las cuatro declaraciones son iguales. Es muy intuitivo y razonable adivinar que el tipo de cadena también sobrecarga HashCode () para devolver el valor del código hash de acuerdo con el contenido de la cadena, por lo que las cadenas con el mismo contenido tienen el mismo código hash.
Al mismo tiempo, esto también ilustra una pregunta: ¿por qué necesitamos usar igual () para comparar cuando sabemos que hashcode () es igual? Se debe a que evita la situación en el ejemplo anterior, porque de acuerdo con la implementación de sobrecarga del método hashcode () de la clase de persona, la clase de persona usará directamente el valor de código hash del tipo de cadena de miembro del miembro como su valor de código hash. Sin embargo, es obvio que una persona ("003") y una cadena ("003") no son iguales, por lo que cuando hashcode () es igual, es igual () también es necesario comparar.
Los siguientes ejemplos pueden usarse como evidencia de la descripción anterior:
System.out.println (nueva persona ("003"). HashCode ()); // 47667System.out.println (nueva cadena ("003"). HashCode ()); // 47667System.out.println (nueva persona ("003"). Equals (nueva cadena ("003"))); // FALSOEl artículo anterior Java utiliza clases personalizadas como un ejemplo de valor clave de hashmap. Este es todo el contenido que comparto con ustedes. Espero que pueda darle una referencia y espero que pueda apoyar más a Wulin.com.