Смещение бита в Эффективном хэш-коде Java () реализация

Я задавался вопросом, мог ли кто-то объяснить подробно что

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

делает в следующей реализации хэш-кода (сгенерированный затмением, но тем же как Эффективный 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;
}

Спасибо!

20
задан Raedwald 14 June 2013 в 12:22
поделиться

3 ответа

По сути, он выполняет операцию 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 .

32
ответ дан 29 November 2019 в 23:36
поделиться

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

8
ответ дан 29 November 2019 в 23:36
поделиться

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

4
ответ дан 29 November 2019 в 23:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: