Посмотрел реализацию HashMap в исходниках Java и вот что увидел:
private static int hash(Object x, int length) {
int h = System.identityHashCode(x);
// Multiply by -127, and left-shift to use least bit as part of hash
return ((h << 1) - (h << 8)) & (length - 1);
}
Вопрос по последней строчке.
Как видно, для получения индекса нужного бакета, у хэш-кода отбрасываются старшие биты с помощью логического AND. Но что это за манипуляции со сдвигами?
1. Как математически доказать, что это лучше простого отбрасывания битов (без этих манипуляций)?
2. Это преобразование могло бы иметь смысл, чтобы увеличить вклад старших битов хешкода, но здесь этого не происходит. Или я ошибаюсь?
3. И еще странность - System.identityHashCode(x) - это де-факто его адрес в памяти. Получается, что HashMap не использует переопределенный HashCode потомка?
Или я не тот кусок кода смотрю?