Какова идея пропуска символов в старом значении String hashCode () в Java - PullRequest
0 голосов
/ 23 декабря 2018

В чем идея пропустить некоторые символы из строки в старых версиях реализации Java String hashCode ():

public int hashCode() {
   int hash = 0;
   int skip = Math.max(1, length()/8);
   for (int i = 0; i < length(); i += skip)
      hash = (hash * 37) + charAt(i);
   return hash;
}

В текущей версии пропуска нет, а простое число - 31 вместо37

1 Ответ

0 голосов
/ 23 декабря 2018

Вероятно, чтобы ускорить вычисления hashCode(), но, как следствие, у него было больше потенциальных коллизий.
Новая версия предпочитает меньше коллизий, но требует большего количества вычислений.

Но на самом деле String s являются неизменяемыми, поэтому в более поздних версиях hashCode() это вычисляется один раз:

public int hashCode() {
    int h = hash; 
    if (h == 0 && value.length > 0) {
        hash = h = isLatin1() ? StringLatin1.hashCode(value)
                              : StringUTF16.hashCode(value);
    }
    return h;
}

Так что в некотором смысле это имеет смыслпредпочтение этому способу, так как оно уменьшает число столкновений и не пропускает некоторые символы в вычислениях hashCode(), не так уж и дорого, поскольку результат кэшируется.

...