Todos sabemos que a língua Java é completamente orientada a objetos. Em Java, todos os objetos são herdados da classe de objeto.
O método Equals compara os endereços apontados pelas referências de dois objetos. HashCode é um método local, que retorna o valor do endereço do objeto. Existem dois métodos na classe Ojbect equals e hashcode. Esses dois métodos são usados para comparar se os dois objetos são iguais.
Por que temos que substituir o método HashCode ao reescrever o método igual?
Pode ser entendido da seguinte forma: Após a reescrita do método Equals, a lógica de negócios para julgar a igualdade de objetos mudará. O designer da classe não deseja comparar a igualdade de dois objetos comparando o endereço de memória. Não faz sentido continuar comparando de acordo com o endereço. Então, é simplesmente alterado juntos.
Outro motivo vem de coleções. Vamos falar sobre isso lentamente abaixo ~
Por exemplo:
Na escola, é através do ID do aluno determinar se essa pessoa pertence.
O cenário no código abaixo é a entrada do registro do aluno, o número 123 do aluno é designado para o aluno Tom, o aluno número 456 é designado para o aluno Jerry e o aluno número 123 é designado para Lily por engano. No entanto, o mesmo número de aluno não deve ocorrer durante o processo de inscrição no status do aluno.
Dependendo dos requisitos situacionais, os objetos duplicados não podem ser adicionados e podem ser implementados por meio de hashset.
Public classe Test {public static void main (string [] args) {Student stu = novo aluno (123, "tom"); hashset <vertware> set = new HashSet <> (); set.add (stu); set.add (novo aluno (456, "jerry")); set.add (New Student (123, "Lily"); while (iterator.hasNext ()) {Student Student = iterator.Next (); System.out.println (student.getStunum () + "---" + student.getName ());}}}; classe estudante {private int atunum; nome de string privado; public student (int atunum, string name) {this.stunum = stunum; this.name = name; public public int () {{return snunum; boolean é igual (objeto obj) {if (this == obj) retorna true; if (obj instanceof student) {if (this.getStunum () == ((student) obj) .getStunum ()) retornar verdadeiro;} retornar false;}} A saída é:
123 --- Lily
456 --- Jerry
123 --- Tom
Com base na saída, descobrimos que a atribuição do aluno número 123 a Lily foi bem -sucedida novamente. O que deu errado?
Vamos dar uma olhada no método Add of Hashset:
public boolean add (e e) {return map.put (e, presente) == null;} De fato, o hashset é implementado através do hashmap, por isso rastreamos o método de put de hashmap:
public v put (K -Key, V Value) {if (tabela == vazio_table) {inflatetable (limiar);} if (key == null) retorna putfornullKey (value); int hash = hash (key); int i = indexfor (hash, tabela.length); E. E. hash && ((k = e.Key) == key || key.equals (k))) {v OldValue = e.Value; e.value = value; e.RecordAccess (this); retorna OldValue;}} modCount ++; addentry (hash, chave, valor, i); retorno nulo;}}1. De acordo com a chave, ou seja, o objeto a ser adicionado pelo Hashset, obtenha o código de hash e o código de hash é usado para executar operações de bits específicas para obter o código de hash;
2. Use o posicionamento do código de hash para encontrar o subscrito da matriz para obter o cabeçalho do link da lista vinculada;
3. Travesse a lista vinculada para descobrir se existe a mesma chave. A base para o julgamento é e.hash == hash && ((k = e.key) == key || key.equals (k)). Ao adicionar Lily, como o método igual é reescrito, a segunda condição deve ser verdadeira ao atravessar Tom; Mas como o método HashCode ainda usa a classe pai, o código de hash de Tom e Lily é diferente, ou seja, o código de hash é diferente e a primeira condição é falsa. Aqui, entendemos que os dois objetos são diferentes, então o hashset adiciona Lily com sucesso.
O motivo é que o método HashCode não está reescrevendo. Aqui está uma modificação:
Public classe Test {public static void main (string [] args) {Student stu = novo aluno (123, "tom"); hashset <vertware> set = new HashSet <> (); set.add (stu); set.add (novo aluno (456, "jerry")); set.add (New Student (123, "Lily"); while (iterator.hasNext ()) {Student Student = iterator.Next (); System.out.println (student.getStunum () + "---" + student.getName ());}}}; classe estudante {private int atunum; nome de string privado; public student (int atunum, string name) {this.stunum = stunum; this.name = name; public public int () {{return snunum; boolean equals(Object obj) {if(this==obj)return true;if(obj instanceof Student){if(this.getStuNum()==((Student)obj).getStuNum())return true;}return false;}@Overridepublic int hashCode() {return getStuNum();}} Saída:
456 --- Jerry
123 --- Tom
Reescreva o método HashCode e retorne o número do aluno. OK, está feito.
Algumas pessoas podem se perguntar, e.hash == hash && ((k = e.key) == key || key.equals (k)) é um pouco complicado? Eu acho que é o suficiente para usar apenas o método igual. Por que você precisa julgar o HashCode de uma só vez?
Porque ao atravessar e julgar a estrutura da lista vinculada do hashmap, a lógica de negócios do método de reescrito é mais complicada de comparar se os objetos são iguais em situações específicas e a lógica de negócios de descer afetará a eficiência da pesquisa. Então, aqui colocamos o julgamento do HashCode em primeiro lugar. Enquanto o código de hash não for igual, você terminará de jogar e não há mais necessidade de chamar iguais complexos. Melhore a eficiência do hashmap em grande parte.
Portanto, o método HashCode é permitir -nos usar classes de coleta como o hashmap normalmente, porque o hashmap determina se os objetos são iguais, tanto o código de hash e é igual à comparação. Esta implementação é para melhorar a eficiência do hashmap.