O valor hashCode de uma String Java é calculado como ( String.hashCode () ):
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
Existem circunstâncias (por exemplo, versão da JVM, fornecedor etc.) sob as quais a expressão a seguir será avaliada como falsa?
boolean expression = "This is a Java string".hashCode() == 586653468
Atualização 1: se você afirmar que a resposta é "sim, existem circunstâncias" - forneça um exemplo concreto de quando "Esta é uma string Java" .hashCode ()! = 586653468. Tente ser o mais específico / concreto que possível.
Atualização 2: Todos sabemos que confiar nos detalhes da implementação de hashCode () é ruim em geral. No entanto, estou falando especificamente sobre String.hashCode () - portanto, mantenha a resposta focada em String.hashCode (). Object.hashCode () é totalmente irrelevante no contexto desta pergunta.
Respostas:
Eu posso ver essa documentação já em Java 1.2.
Embora seja verdade que, em geral, você não deve confiar em uma implementação de código de hash permanecendo a mesma, agora é um comportamento documentado
java.lang.String
, portanto, alterá-lo contará como quebra de contratos existentes.Sempre que possível, você não deve confiar em códigos de hash permanecendo o mesmo em todas as versões etc - mas na minha mente
java.lang.String
é um caso especial, simplesmente porque o algoritmo tenha sido especificado ... desde que você está disposto a abandonar a compatibilidade com versões anteriores à algoritmo foi especificado, é claro.fonte
Encontrei algo sobre o JDK 1.0 e 1.1 e> = 1.2:
Algo diferente, porque você parece precisar de um número: que tal usar o CRC32 ou MD5 em vez do código de hash e você está pronto - sem discussões e sem preocupações ...
fonte
Você não deve confiar em um código de hash igual a um valor específico. Só que ele retornará resultados consistentes dentro da mesma execução. Os documentos da API dizem o seguinte:
EDIT Como o javadoc para String.hashCode () especifica como o código de hash de uma String é calculado, qualquer violação disso violaria a especificação pública da API.
fonte
Como dito acima, em geral você não deve confiar no código hash de uma classe que permanece o mesmo. Observe que mesmo execuções subsequentes do mesmo aplicativo na mesma VM podem produzir valores de hash diferentes. AFAIK, a função de hash da Sun JVM calcula o mesmo hash em cada execução, mas isso não é garantido.
Observe que isso não é teórico. A função hash para java.lang.String foi alterada no JDK1.2 (o hash antigo teve problemas com cadeias hierárquicas como URLs ou nomes de arquivos, pois tendia a produzir o mesmo hash para cadeias de caracteres que diferiam apenas no final).
java.lang.String é um caso especial, pois o algoritmo de seu hashCode () está (agora) documentado, portanto você provavelmente pode confiar nisso. Eu ainda consideraria uma prática ruim. Se você precisar de um algoritmo de hash com propriedades especiais documentadas, basta escrever um :-).
fonte
Outra questão (!) Com que se preocupar é a possível alteração de implementação entre as versões iniciais / tardias do Java. Não acredito que os detalhes da implementação estejam definidos, e potencialmente uma atualização para uma versão futura do Java pode causar problemas.
Resumindo, eu não confiaria na implementação de
hashCode()
.Talvez você possa destacar qual problema está realmente tentando resolver usando esse mecanismo, e isso destacará uma abordagem mais adequada.
fonte
switch
as declarações sobre cordas compilar para código depender de um determinado código de hash fixo, muda paraString
's algoritmo de código hash iria quebrar o código existente ...Apenas para responder sua pergunta e não continuar com nenhuma discussão. A implementação do Apache Harmony JDK parece usar um algoritmo diferente, pelo menos parece totalmente diferente:
Sun JDK
Apache Harmony
Sinta-se livre para verificar você mesmo ...
fonte
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
menos que eu esteja enganado, isso ocorre porque o Android usa a implementação da Sun do objeto String sem alterações.Se você estiver preocupado com alterações e possivelmente com VMs incompatíveis, copie a implementação de código de hash existente em sua própria classe de utilitário e use-a para gerar seus códigos de hash.
fonte
O hashcode será calculado com base nos valores ASCII dos caracteres na String.
Esta é a implementação na classe String é a seguinte
Colisões no código hash são inevitáveis. Por exemplo, as cadeias "Ea" e "FB" fornecem o mesmo código hash que 2236
fonte