代码之家  ›  专栏  ›  技术社区  ›  Mark Pope

有效Java hashCode()实现中的位移位

  •  20
  • Mark Pope  · 技术社区  · 14 年前

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

    在以下hashcode实现中执行(由eclipse生成,但与Effective 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;
    }
    

    谢谢!

    3 回复  |  直到 11 年前
        1
  •  32
  •   Jon Skeet    14 年前

    基本上,它将long的前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位将被忽略,这不会使它成为一个很好的散列。这样,一位输入的变化 总是 导致哈希值的单个位发生更改。诚然,你仍然可以很容易地得到碰撞-改变 二者都 例如,第7位和第39位,或者其他任何一对32位的位置相隔——但这是必然的,因为你是从2开始的 可能值为2 32

        2
  •  8
  •   corsiKa    14 年前

        3
  •  4
  •   Alex Martelli    14 年前

    它需要一个(64位) long l ,异或将上半部分和下半部分(各32位)转换为64位结果的下32位,然后只取下32位 (int) 演员阵容。