2010-05-13 9 views
18

Tôi đã tự hỏi nếu ai đó có thể giải thích một cách chi tiết những gìBit-chuyển trong Effective Java hashCode() thực hiện

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

không trong việc thực hiện sau hashcode (tạo ra bởi nhật thực, nhưng cũng giống như Java hiệu quả) :

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; 
} 

Cảm ơn!

Trả lời

28

Về cơ bản nó XORs 32 bit hàng đầu của một dài với 32 bit dưới cùng. Đây là phiên bản đã phát nổ:

// 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; 

Để trả lời nhận xét của bạn: bạn có giá trị dài phải được chuyển đổi thành một phần của băm (kết quả chỉ là 32 bit). Làm thế nào bạn sẽ làm điều đó? Bạn có thể chỉ mất 32 bit dưới cùng - nhưng sau đó điều đó có nghĩa là thay đổi trong chỉ 32 bit hàng đầu sẽ bị bỏ qua, điều này sẽ không làm cho nó trở thành một băm tốt. Bằng cách này, thay đổi trong một bit đầu vào luôn luôn dẫn đến thay đổi một bit duy nhất của hàm băm. Phải thừa nhận rằng bạn vẫn có thể dễ dàng bị va chạm - thay đổi cả hai ví dụ bit 7 và 39, hoặc bất kỳ cặp bit nào khác cách nhau 32 vị trí - nhưng đó là trường hợp bắt buộc, với điều kiện là bạn đang chuyển từ 2 giá trị cho 2 .

+0

Lý do để thực hiện việc này là gì? Bạn sẽ không nhận được một hashcode hợp lệ mà không làm nó? –

+0

@Scobal: Tôi đã mở rộng câu trả lời của mình để giải thích thêm. –

+0

Và có một ý nghĩa của hằng số 31 (int nguyên tố) ở đây hoặc chúng ta có thể lấy số nguyên tố? – Diffy

7

Phải mất một số 64 bit, chia nhỏ một nửa và xói hai nửa lại với nhau (về bản chất).

4

Phải mất (64 bit) longl, độc quyền hoặc nửa trên và dưới (32 bit mỗi) vào 32 bit cuối cùng của kết quả 64 bit, sau đó chỉ lấy 32 bit dưới cùng với (int) truyền.