Prefácio
Como todos sabemos, java.lang.Object possui um método hashcode () e um equals (), que desempenham um papel importante no design de software. Reescreva esses dois métodos em algumas classes para realizar algumas funções importantes.
1. Por que usar hashcode ()?
Os elementos do conjunto são desordenados e não repetíveis. Então, qual é a base para julgar se dois elementos são repetidos?
Algumas pessoas dizem: Object.equal() é obviamente usado para comparar se os objetos são iguais. No entanto, há um grande número de objetos no conjunto, e o número de comparações de elementos de objeto adicionado ao conjunto aumentará gradualmente, reduzindo bastante a eficiência da operação do programa. O Java usa o algoritmo de hash (também chamado de algoritmo de hash) para resolver esse problema. O objeto (ou dados) é mapeado diretamente para um endereço de acordo com um algoritmo específico, e a eficiência de acesso do objeto é bastante aprimorada.
Dessa forma, quando um conjunto contendo um grande número de elementos precisa adicionar um elemento (objeto), primeiro chame o hashcode () desse elemento e você pode posicionar o local de armazenamento real desse elemento de uma só vez. Se não houver elemento nesta posição, significa que esse objeto é armazenado na coleção definido pela primeira vez, e o objeto será armazenado diretamente nesta posição; Se houver um objeto nesta posição, ligue para igual () para ver se os dois objetos são iguais. Se o mesmo for verdadeiro, descarte o elemento e não existe. Se não for igual, hash para outros endereços.
Essa também é a razão pela qual, quando o conjunto de conjuntos armazena dados do tipo de objeto, é necessário não apenas reescrever o método hashcode () do objeto, mas também reescrever o método iguals ().
2. Como uso hashcode ()?
A relação entre o valor de retorno de hashcode () e iguals ()
Aqui está um exemplo. No desenvolvimento real do software, é melhor reescrever esses dois métodos.
Public Classe Funcionário {int EmployeeID; Nome da string; @Override public boolean é igual (objeto obj) {if (obj == this) retorna true; Funcionário emp = (funcionário) obj; if (FEXYID.EQUALS (EMP.GETEMPLAYEEID ()) && name == EMP.GetName ()) retorna true; retornar falso; } @Override public int hashCode () {int hash = 1; hash = hash * 17 + funcionárioID; hash = hash * 31 + name.hashcode (); retornar hash; }}Os métodos iguais () e hashcode () são usados para comparar na mesma classe, especialmente ao armazenar o mesmo objeto de classe no contêiner, como definido para armazenar objetos na mesma classe.
Aqui precisamos primeiro entender um problema:
Dois objetos com equals () iguais, hashcode () devem ser iguais e dois objetos com igual () não iguais, não podem provar que seu hashcode () não é igual. Em outras palavras, para dois objetos cujo método iguals () não é igual, o hashcode () pode ser igual.
Aqui o HashCode é como o índice de cada caractere no dicionário, e iguals () é como comparar palavras diferentes com o mesmo personagem no dicionário. Assim como no dicionário, pesquisando as duas palavras "self" e "espontâneo" sob a palavra "eu" no dicionário, se igual a () é usado para determinar a igualdade das palavras, é a mesma palavra. Por exemplo, as duas palavras comparadas por iguais () são "self", então os valores obtidos pelo método hashcode () devem ser iguais neste momento; Se o método iguals () compara as palavras "self" e "espontâneo", o resultado é que você não quer esperar, mas essas duas palavras pertencem às palavras "eu" e, assim, ao procurar índices, ou seja, hashcode () é o mesmo. Se Equals () compara as palavras "self" e "eles", os resultados também são diferentes e os resultados obtidos pelo HashCode () também são diferentes no momento.
Por outro lado: o hashcode () é diferente e igual a () pode ser introduzido; hashcode () é igual, iguais () pode ser igual ou não pode ser igual.
Na classe de objeto, o método hashcode () é um método local, que retorna o valor do endereço do objeto. O método iguals () na classe de objeto também compara os valores de endereço dos dois objetos. Se iguals () for igual, significa que os valores de endereço dos dois objetos também são iguais. Obviamente, o hashcode () é igual.
Como a igual é mais precisa para comparar elementos iguais, por que usar o método hashcode ()?
Como o algoritmo de hash fornece alta eficiência em encontrar elementos, se você deseja descobrir se uma coleção contém um objeto, como escrever o código aproximado do programa?
Você geralmente retira cada elemento um a um para comparar com o objeto que está procurando. Quando você achar que o resultado da comparação do método igual entre um elemento e o objeto que você está procurando, pare de pesquisar e retorne informações positivas. Caso contrário, retorne informações negativas. Se houver muitos elementos em uma coleção, como 10.000 elementos e não conter o objeto que você está procurando, isso significa que seu programa precisa retirar 10.000 elementos da coleção e comparar um por um para obter uma conclusão.
A classe Object define um método hashcode () para retornar o código de hash de cada objeto Java. Ao procurar um objeto da coleta de hashset, o sistema Java chama primeiro o método hashcode () do objeto para obter a tabela de código de hash do objeto e, em seguida, encontra a área de armazenamento correspondente com base no hash e, finalmente, obtém cada elemento na área de armazenamento e o compara ao objeto para o método igual. Dessa forma, você pode obter a conclusão sem atravessar todos os elementos da coleção. Pode -se observar que a coleção de hashset tem um bom desempenho de recuperação de objetos.
No entanto, a eficiência de armazenar objetos na coleção de hashset é relativamente baixa, porque ao adicionar um objeto à coleção de hashset, o código de hash do objeto deve ser calculado primeiro e o local de armazenamento do objeto na coleção é determinado com base nesse código de hash. Para garantir que os objetos de instância de uma classe possam ser armazenados normalmente no hashset, os resultados dos dois objetos de instância dessa classe devem ser iguais quando comparados com o método iguals () são iguais; isto é, se o resultado de obj1.equals(obj2) for verdadeiro, o resultado da seguinte expressão também deverá ser true:obj1.hashCode() == obj2.hashCode() .
Em outras palavras: quando reescrevermos o método igual de um objeto, devemos reescrever seu método HashCode. Se não reescrevermos seu método HashCode, o método HashCode no objeto sempre retorna o endereço de hash de um objeto, e esse endereço nunca será igual. Portanto, mesmo que o método igual seja reescrito neste momento, não haverá efeito específico, porque se o método HashCode não quiser esperar, ele não chamará o método igual para comparação, por isso não faz sentido.
A maioria das estruturas de dados usa o método igual para determinar se eles contêm um elemento, por exemplo:
List <String> List = Arrays.asList ("A", "B", "C"); Boolean contém = list.contains ("B"); Essa variável contém resultado é verdadeira porque, embora "B" seja diferentes instâncias (além disso, a residência da string é ignorada), elas são iguais.
Eles usam uma maneira rápida de comparar (reduz a igualdade de instância potencial) em vez de comparar cada elemento contido na instância. A comparação rápida requer apenas a comparação dos seguintes aspectos:
Comparação de atalho significa que, comparando os valores de hash, ele pode substituir uma instância por um valor inteiro. Instâncias com o mesmo código de hash não são necessariamente iguais, mas instâncias com igualdade devem ter o mesmo valor de hash. (ou deve ter, discutiremos isso em breve) Essas estruturas de dados são frequentemente nomeadas por essa técnica, e elas podem ser identificadas pelo hash, entre as quais o Hashmap é o representante mais famoso.
Eles geralmente funcionam assim:
Ao adicionar um elemento, seu código de hash é usado para calcular o índice da matriz interna (ou seja, o chamado balde)
Se sim, elementos desiguais têm o mesmo código de hash, eles acabam no mesmo balde e reunidos, por exemplo, adicionando à lista.
Quando uma instância executa contém operações, seu código de hash será usado para calcular o valor do balde (valor do índice) e a instância será comparada apenas quando os elementos existirem no valor do índice correspondente.
Portanto, é igual, o HashCode é definido na classe de objeto.
Se o HashCode for usado como um atalho para determinar a igualdade, há apenas uma coisa com a qual devemos nos preocupar: objetos iguais devem ter o mesmo hashcode, e é por isso que se substituímos o método igual, precisamos criar uma implementação de código de hash que corresponda!
Caso contrário, objetos iguais podem não ter o mesmo código de hash, porque eles chamarão a implementação padrão dos objetos.
Citação de documentos oficiais
Convenção Geral HashCode:
Ao chamar o mesmo objeto em execução em um aplicativo Java, o método HashCode deve sempre retornar o mesmo número inteiro. Esse número inteiro não precisa ser consistente em diferentes aplicativos Java. De acordo com equals(Object) , se dois objetos forem iguais, os dois objetos chamam o método HashCode deverá produzir o mesmo resultado.
De acordo com equals(Object) , se os dois objetos não forem iguais, chamando o método HashCode não produzirá necessariamente resultados inteiros diferentes. No entanto, os programadores devem perceber que a produção de diferentes resultados inteiros para objetos desiguais provavelmente melhorará o desempenho da tabela de hash.
Implementação de hashcode
Aqui está uma implementação simples de person.hashcode() :
@OverridePublic int hashcode () {return Objects.hash (primeironame, sounName);}A pessoa calcula o código de hash combinando vários campos. Todos são calculados pela função de hash do objeto.
Selecione um campo
Mas quais campos estão relacionados? Os requisitos nos ajudarão a responder a esta pergunta:
Se um objeto igual deve ter o mesmo código de hash, o código de hash calculado não deve incluir campos que não sejam usados para verificações de igualdade. (Caso contrário, os dois objetos são apenas que esses campos são diferentes, mas ainda podem ser iguais, mas os códigos de hash dos dois objetos serão diferentes no momento.) Portanto, o subconjunto dos campos usados quando os campos do grupo hash deverão ser iguais. Os mesmos campos são usados por padrão, mas há alguns detalhes a serem considerados.
Resumir
Entendemos que o cálculo do código de hash é comprimir um valor inteiro igual: objetos iguais devem ter o mesmo código de hash e, para considerações de desempenho, é melhor compartilhar o mesmo código de hash o máximo possível objetos desiguais.
Isso significa que, se o método igual for reescrito, o método HashCode deverá ser reescrito.
Ao implementar o HashCode, usa os mesmos campos usados em iguais (ou em um subconjunto de campos usados em iguais)
É melhor não incluir campos mutáveis. Não considere chamar o HashCode para coleções. Se não houver modo específico de entrada especial, tente usar um algoritmo de hash geral.
Ok, o acima é o conteúdo inteiro deste artigo. Espero que o conteúdo deste artigo tenha certo valor de referência para o estudo ou trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar. Obrigado pelo seu apoio ao wulin.com.