Por que String.hashCode () em Java tem muitos conflitos? [fechadas

Por que String.hashcode () tem tantos conflito

Estou lendo o String.hashCode () em jdk1.6, abaixo estão os códigos

public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;

        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h;
    }
    return h;
}

Isto me parece bastante confuso porque tem muitos conflitos; embora não seja necessário ser único (ainda podemos confiar nos iguais ()), mas menos conflitos significam melhor desempenho sem visitar as entradas em uma lista vinculada.

Suponha que tenhamos dois caracteres e, desde que possamos encontrar duas seqüências correspondentes abaixo da equação, teremos o mesmo código hash ()

a * 31 +b = c * 31 +d

Será fácil concluir que(a-c) * 31 = d-b um exemplo fácil é make a-c = 1 ed-b = 31; então eu escrevi abaixo códigos para teste simples

public void testHash() {
    System.out.println("A:" + (int)'A');
    System.out.println("B:" + (int)'B');
    System.out.println("a:" + (int)'a');

    System.out.println("Aa".hashCode() + "," + "BB".hashCode());
    System.out.println("Ba".hashCode() + "," + "CB".hashCode());
    System.out.println("Ca".hashCode() + "," + "DB".hashCode());
    System.out.println("Da".hashCode() + "," + "EB".hashCode());        
}

it imprimirá abaixo dos resultados, o que significa que todas as strings têm o mesmo código hash (), e é fácil fazê-lo em um loo

A:65 
B:66
a:97
2112,2112
2143,2143
2174,2174
2205,2205

pior ainda, suponha que tenhamos 4 caracteres na string, de acordo com o algoritmo, suponha que os 2 primeiros caracteres produzam a2, o 2º caractere 2 produza b2; o código hash ainda seráa2 * 31^2 + b2 assim, com a2 e b2 iguais entre 2 strings, obteremos mais strings com o conflito hashcode (). esses exemplos são "AaAa", "BBBB" e assim por diante; então teremos 6 caracteres, 8 caracteres ......

suponha que na maioria das vezes usamos caracteres na tabela ascii em uma string que será usada em um hashmap ou hashtable, então o número primo escolhido 31 aqui é definitivamente muito pequeno;

ma solução fácil é usar um número primo maior (felizmente, 257 é um número primo) que pode evitar esse conflito. é claro, escolher um número muito grande fará com que o valor int retornado seja excedido se a string for muito longa, mas presumo que na maioria das vezes a string usada como chave não seja tão grande? é claro, ele ainda pode retornar um valor longo para evitar iss

abaixo é a minha versão modificada do betterhash () que pode resolver esses conflitos facilmente executando os códigos que serão impressos abaixo dos valores, o que é eficaz para resolver esse problem

16802,17028
17059,17285
17316,17542
17573,17799

mas por que o jdk não corrige isso? valeu

@Test
public void testBetterhash() {
    System.out.println(betterHash("Aa") + "," + betterHash("BB"));      
    System.out.println(betterHash("Ba") + "," + betterHash("CB"));
    System.out.println(betterHash("Ca") + "," + betterHash("DB"));
    System.out.println(betterHash("Da") + "," + betterHash("EB"));
}

public static int betterHash(String s) {
    int h = 0;
    int len = s.length();

    for (int i = 0; i < len; i++) {
        h = 257*h + s.charAt(i);
    }
    return h;
}

questionAnswers(8)

yourAnswerToTheQuestion