1.Por que 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? "Obviamente, object.Equal () é usado para comparar se os objetos são iguais", disse um certo macaco. 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 de conjuntos 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 o objeto é armazenado na coleção definida 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.
2.Como usar hashcode ()?
O idioma Java possui cinco requisitos que devem ser seguidos para igual () no design do macaco.
simetria. Se A.Equal (b) retornar "True", então B.Equal (a) também deve retornar "True".
Reflexivo. A.Equal (a) deve retornar "verdadeiro".
Transitivo. Se A.Equal (b) retornar "True" e B.Equal (c) retornar "True", então C.Equal (a) deve retornar "verdadeiro".
consistência. Se A.Equal (B) retornar "True", desde que o conteúdo de A e B permaneça inalterado, não importa quantas vezes a A.Equal (B) deva retornar "True".
De qualquer forma, o A.Equals (nulo) sempre retorna "falso"; A.Equals (objetos de diferentes tipos e a) sempre retorna "false".
A relação entre o valor de retorno de hashcode () e iguals ().
Se A.Equals (B) retornar "True", o HashCode () de A e B deve ser igual.
Se a.quals (b) retornar "falsa", o código de hashCode () de A e B pode ser igual ou pode ser desigual.
Aqui está um exemplo. No desenvolvimento real do software, é melhor reescrever esses dois métodos.
Public Classe Funcionário {int EmployeeID; Nome da string; // Outros métodos estariam aqui @Override public boolean equals (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; }}3. A seguir, é apresentado o foco no método de implementação hashcode () de classes comumente usadas.
Hascode () da classe String
public int hashCode () {int h = hash; if (h == 0) {int off = offset; char val [] = valor; int len = count; for (int i = 0; i <len; i ++) {h = 31*h+val [off ++]; } hash = h; } retornar h; }A coisa mais interessante sobre esse código é o método de implementação do hash. O valor final do hash calculado é:
s [0] 31n-1 + s [1] 31n-2 +… + s [n-1]
S [i] é o i-ésimo caractere de uma corda e n é o comprimento de uma corda. Então, por que usar 31 aqui em vez de outros números?
31 é um número primo estranho. Se o multiplicador for um número par e a multiplicação transborda, as informações serão perdidas porque a multiplicação com 2 é equivalente à operação de mudança. Os benefícios do uso de números primos não são óbvios, mas os resultados de hash são usados convencionalmente para calcular os resultados do hash. 31 tem um bom recurso, que é usar turno e subtração em vez de multiplicação para obter melhor desempenho: 31*i == (i << 5) -i. As VMs podem concluir automaticamente essa otimização. (De eficaz Java)
hascode () da classe de objeto
hashcode () é um método nativo na classe de objeto. Como chamar métodos nativos?
public nativo int hashcode ();
A classe de método nativa da classe de objeto pode ser encontrada aqui. Por favor, leia outro blog para análise detalhada
estático jninativethod métodos [] = {{"hashcode", "() i", (void *) e jvm_ihashcode}, {"wait", "(j) v", (void *) e jvm_monitorwait}, {"notify", "() v", (Void *) e {"notifyall", "() v", (void *) e jvm_monitorNotifyAll}, {"clone", "() ljava/lang/object;", (void *) e jvm_clone},};O código -fonte inclui getClass () (consulte a linha58), etc. hashcode () (consulte a linha43) é definido como um ponteiro para jvm_ihashcode.
JVM.CPP define a função JVM_IHASHCODE (Linha 504). Esta função chama ObjectSynchronizer :: FasthashCode, que é determinado em synchronizer.cpp. Para a implementação do FasthashCode na linha 576 e get_next_hash na linha 530, você pode consultar a implementação do FasthashCode na linha 576 e get_next_hash na linha 530.