Esta é uma pergunta muito clássica em Java e é frequentemente feita durante as entrevistas. De fato, muitos livros ou artigos mencionaram que você precisa sobrecarregar os métodos HashCode () e Equals () para realizar a busca por chaves personalizadas no Hashmap. No entanto, parece que poucos artigos falam sobre por que você precisa fazer isso e que consequências serão causadas por não fazer isso, então escreverei este artigo para explicá -lo.
Primeiro de tudo, o que acontece se usarmos diretamente a aula de pessoa a seguir como chave e armazená -la no hashmap?
public class Pessoa {private String ID; pessoa pública (string id) {this.id = id; }} importar java.util.hashmap; public classe principal {public static void main (string [] args) {hashmap <pessoa, string> map = new hashmap <pessoa, string> (); map.put (nova pessoa ("001"), "Findingesa"); map.put (nova pessoa ("002"), "linyin"); map.put (nova pessoa ("003"), "henrylin"); map.put (nova pessoa ("003"), "descobries"); System.out.println (map.toString ()); System.out.println (map.get (new pessoa ("001"))); System.out.println (map.get (new Person ("002"))); System.out.println (map.get (new Person ("003"))); }}Então, qual é o resultado da saída?
{Pessoa@6e4d4d5e = henrylin, pessoa@275Cea3 = Findingesea, pessoa@15128ee5 = FindingingSealy, pessoa@4513098 = linyin} nullnullnullPodemos ver que existem dois problemas aqui:
1. Durante o processo de adição, adicionamos o par de valores de chave de key = nova pessoa ("003") duas vezes. Na expectativa, deve haver apenas um par de valores -chave no hashmap. Como a chave (esperada) é a mesma, ela não deve ser adicionada repetidamente. O value = "achatingSealy" adicionado na segunda vez deve substituir o valor original = "henrylin". Mas, na entrada, descobrimos que a situação esperada não ocorreu, mas existem dois pares de valor-chave de value = "achtingSealy" e value = "henrylin" no hashmap, e seus valores-chave ainda são diferentes, o que está obviamente errado.
2. Ao obter o valor do valor, usamos objetos de três pessoas para pesquisar. Esses três objetos são os mesmos que os três valores -chave que acabamos de armazenar (em expectativa), mas a pesquisa é de três valores nulos, o que obviamente também está errado.
Portanto, o método correto foi realmente descrito em muitos lugares. A classe Pessoa é diretamente modificada, os métodos sobrecarregados iguais e hashcode, e a classe de pessoa modificada é a seguinte:
public class Pessoa {private String ID; pessoa pública (string id) {this.id = id; } @Override public boolean é igual (objeto o) {if (this == O) retorna true; if (o == null || getClass ()! = O.getclass ()) retorna false; Pessoa pessoa = (pessoa) o; if (id! = null?! id.equals (pessoa.id): pessoa.id! = null) retornar false; retornar true; } @Override public int hashCode () {return id! = Null? id.hashcode (): 0; }}Então, quando reexectamos o procedimento de inspeção acima, os resultados são os seguintes:
{Pessoa@ba31 = Findingesea, pessoa@ba32 = linyin, pessoa@ba33 = descobrigem} achoundingSealinyInfindingingsEalyComo pode ser visto, todos os destaques e erros apontados foram corrigidos. Então, por que isso está acontecendo?
No Hashmap, a ordem de comparação das chaves de pesquisa é:
1. Calcule o código de hash do objeto para ver se ele existe na tabela.
2. Verifique se o objeto na localização do código de hash correspondente é igual ao objeto atual.
Obviamente, a primeira etapa é usar o método hashcode (), e a segunda etapa é usar o método iguals (). Quando nenhuma sobrecarga é executada, esses dois métodos da classe de objeto serão chamados por padrão nessas duas etapas. No objeto, o método de cálculo do código de hash é calculado com base no endereço do objeto. Os endereços de objeto das duas pessoas ("003") são diferentes, portanto, seu código de hash também é diferente. Naturalmente, o hashmap não os tratará como a mesma chave. Ao mesmo tempo, no padrão igual () do objeto, ele também é comparado com base no endereço do objeto. Naturalmente, uma pessoa ("003") e outra pessoa ("003") não são iguais.
Depois de entender isso, é fácil descobrir por que você precisa sobrecarregar os métodos hashcode () e iguais.
• Sobrecarregar o hashcode () é obter o mesmo código de hash para a mesma chave, para que o hashmap possa ser posicionado na chave que especificou.
• Sobrecarregamento iguals () é mostrar hashmap que o objeto atual e o objeto salvos na chave são iguais, para que possamos realmente obter o par de valores-chave correspondente à chave.
Há outro detalhe. Na classe Pessoa, a ênfase no método hashcode () é:
@OverridePublic int hashcode () {return id! = Null? id.hashcode (): 0;}O ponto que pode ficar intrigado aqui é: por que o código de hash de uma variável de string de tipo pode ser usado como o valor do código de hash da classe Pessoa? Os códigos de hash de nova pessoa (New String ("003")) e nova pessoa (nova string ("003")) são iguais?
Vamos dar uma olhada na saída do seguinte código:
System.out.println ("Findingesa" .hashCode ()); System.out.println ("Findingesa" .hashCode ()); System.out.println (new String ("Findingesa"). HashCode ()); System.out.println (novo String ("Findingesea"). HashCode ()); 728795174728795174728795174728795174Você pode ver que as saídas das quatro instruções são todas iguais. É muito intuitivo e razoável adivinhar que o tipo de string também sobrecarrega o hashcode () para retornar o valor do código de hash de acordo com o conteúdo da string; portanto, as strings com o mesmo conteúdo têm o mesmo código de hash.
Ao mesmo tempo, isso também ilustra uma pergunta: por que precisamos usar iguais () para comparação quando sabemos que o hashcode () é igual? É porque evita a situação no exemplo acima, porque, de acordo com a implementação da sobrecarga do método hashcode () da classe Pessoa, a classe Pessoa usará diretamente o valor do código de hash do ID do membro do tipo String como seu valor de código de hash. No entanto, é óbvio que uma pessoa ("003") e uma string ("003") não são iguais; portanto, quando o hashcode () é igual, iguais () também é necessário para comparar.
Os exemplos a seguir podem ser usados como evidência da descrição acima:
System.out.println (new Pessoa ("003"). Hashcode ()); // 47667system.out.println (new String ("003"). Hashcode ()); // 47667system.out.println (nova pessoa ("003"). Equals (new String ("003"))); // falseO artigo acima Java usa classes personalizadas como um exemplo de valor chave do hashmap. Este é todo o conteúdo que compartilho com você. Espero que possa lhe dar uma referência e espero que você possa apoiar mais o wulin.com.