Подтвердить что ты не робот

Бит-сдвиг в эффективной реализации Java hashCode()

Мне было интересно, может ли кто-нибудь подробно объяснить, что

(int)(l ^ (l >>> 32));

делает в следующей реализации hashcode (сгенерированной eclipse, но так же, как и Эффективная Java):

private int i;
private char c; 
private boolean b;
private short s;
private long l;
private double d;
private float f;

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + i;
    result = prime * result + s;
    result = prime * result + (b ? 1231 : 1237);
    result = prime * result + c;
    long t = Double.doubleToLongBits(d);
    result = prime * result + (int) (t ^ (t >>> 32));
    result = prime * result + Float.floatToIntBits(f);
    result = prime * result + (int) (l ^ (l >>> 32));
    return result;
}

Спасибо!

4b9b3361

Ответ 1

В основном это XOR - верхние 32 бита длинной с нижними 32 битами. Здесь взорванная версия:

// Unsigned shift by 32 bits, so top 32 bits of topBits will be 0,
// bottom 32 bits of topBits will be the top 32 bits of l
long topBits = l >>> 32;

// XOR topBits with l; the top 32 bits will effectively be left
// alone, but that doesn't matter because of the next step. The
// bottom 32 bits will be the XOR of the top and bottom 32 bits of l
long xor = l ^ topBits;

// Convert the long to an int - this basically ditches the top 32 bits
int hash = (int) xor;

Чтобы ответить на ваш комментарий: у вас есть длинное значение, которое должно быть преобразовано в int, чтобы быть частью хэша (результат должен быть только 32 бита). Как вы это сделаете? Вы могли бы просто взять нижние 32 бита - но тогда это означает, что изменения только в верхних 32 битах будут проигнорированы, что не сделает его очень хорошим хешем. Таким образом, изменение одного бита ввода всегда приводит к изменению одного бита хэша. По общему признанию, вы все равно можете легко получить столкновения - измените, например, как биты 7, так и 39, или любую другую пару битов 32, расположенных отдельно друг от друга, - но это связано с тем, что вы переходите от 2 64 возможные значения до 2 32.

Ответ 2

Требуется 64-битное число, разделяет его пополам и сопоставляет две половины (по существу).

Ответ 3

Требуется (64-разрядная) long l, эксклюзивная, или верхняя и нижняя половины (по 32 бита каждая) в нижние 32 бита 64-битных результатов, а затем принимает только нижнюю 32 бит с приложением (int).