2013-07-31 57 views
13

Tôi đang tìm thuật toán của Object.hashCode().Thuật toán Object.hashCode()

Mã này có nguồn gốc từ Object.java.

Đây có phải là vì

(a) đang trong assembly-- không bao giờ là trong Java hoặc bất kỳ HLL khác ở tất cả các

hoặc

(b) nó chỉ đơn giản là không được tiết lộ

?

Trong cả hai trường hợp, tôi đang tìm cách giữ thuật toán (mã giả hoặc một số giải thích chi tiết) về "cách hashCode() được tính" - các tham số sẽ tính toán và tính toán chinh no?

Xin lưu ý: Đó là hashCode() of Object tôi đang tìm tôi-- không khác tương tự như của Chuỗi hoặc HashMap/table.

// ============================================ ==============================

các new Java docs - jdk 8 giờ nói

"The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal." 
+3

Tôi tin rằng nó là nguồn gốc bởi vì hashCode của đối tượng là một định danh địa chỉ bộ nhớ, không thực sự là một băm của các lĩnh vực của đối tượng . –

+0

Ai đó cần cập nhật tài liệu bạn đang trích dẫn. Bởi vì nó hoàn toàn sai. –

Trả lời

0

Đó là vì nó dựa trên các chi tiết cấp thấp không được tiếp xúc với mã Java. Một số phần cơ bản của thư viện chuẩn (như java.lang.Object) phải được triển khai trong mã gốc.

Như một sang một bên, bạn có thể tìm thấy ít nhất một interesting article chi tiết hơn về triển khai HotSpot.

1

hashCode là phương pháp gốc, có nghĩa là thư viện hệ thống được gọi nội bộ. Điều này là do lý do hashcode nội bộ sẽ cố gắng tạo ra một số tùy thuộc vào vị trí bộ nhớ đối tượng. Mã này phụ thuộc máy và có lẽ được viết bằng C.

Nhưng nếu bạn thực sự quan tâm để xem mã nguồn gốc, sau đó làm theo này:

http://hg.openjdk.java.net/jdk7/jdk7-gate/jdk/file/e947a98ea3c1/src/share/native/java/

+0

Vâng, thats thing-- là đối tượng bộ nhớ vị trí param duy nhất để đi vào hashCode() tính toán? làm thế nào nó được thực hiện-- trên các bit cấp thấp của địa chỉ có thể? – Roam

8

Mặc dù Javadoc, các algo chỉ có thể sử dụng địa chỉ làm đầu vào. Điều này có nghĩa rằng mặc dù các đối tượng mới sử dụng cùng một địa chỉ trong không gian eden chúng sẽ không có cùng một hashCode.

Có một số thuật toán có thể sử dụng và không phải tất cả đều sử dụng địa chỉ.

Lưu ý: hashCode() là 31 bit.

BTW Bạn có thể đặt nó bằng Unsafe.putInt(object, 1, value) trên Điểm phát sóng.

Set<Integer> ints = new LinkedHashSet<>(); 
int negative = 0, nonneg = 0; 
for (int i = 0; i < 100; i++) { 
    System.gc(); 
    for (int j = 0; j < 100; j++) { 
     int h = new Object().hashCode(); 
     ints.add(h); 
     if (h < 0) negative++; 
     else nonneg++; 
    } 
} 
System.out.println("unique: " + ints.size() + " negative: " + negative + " non-neg: " + nonneg); 

in

unique: 10000 negative: 0 non-neg: 10000 

Sử dụng không an toàn

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); 
theUnsafe.setAccessible(true); 
Unsafe unsafe = (Unsafe) theUnsafe.get(null); 

Object o = new Object(); 
System.out.println("From header " + Integer.toHexString(unsafe.getInt(o, 1L))); 
// sets the hashCode lazily 
System.out.println("o.hashCode() " + Integer.toHexString(o.hashCode())); 
// it's here now. 
System.out.println("after hashCode() From header " + Integer.toHexString(unsafe.getInt(o, 1L))); 
unsafe.putInt(o, 1L, 0x12345678); 
System.out.println("after change o.hashCode() " + Integer.toHexString(o.hashCode())); 

in

From header 0 
o.hashCode() 2260e277 
after hashCode() From header 2260e277 
after change o.hashCode() 12345678 
+1

"hashCode() chỉ sử dụng địa chỉ của đối tượng" sẽ nhất quán với các thông số kỹ thuật tại http://www.docjar.com/docs/api/java/lang/Object.html#hashCode. nhưng sau đó bạn đang nói "mặc dù các đối tượng mới sử dụng cùng một địa chỉ, chúng sẽ không có cùng một hashCode". làm thế nào sau đó là tie này bị hỏng? một số vị trí bộ nhớ khác so với địa chỉ tham chiếu của đối tượng (như của một số thành viên, địa chỉ kết thúc/dung lượng bộ nhớ mà nó sử dụng, một số nội dung trên dấu thời gian ...?) – Roam

+0

mặc dù đáp ứng "cùng một hashCode cho cùng một đối tượng tại mọi cuộc gọi của hashCode() trong một lần thực hiện ", chỉ duy nhất địa chỉ của đối tượng cho phép tính này không cảm thấy đúng - quá nhất quán với không gian bộ nhớ, không phải là mạnh mẽ trên sự ngẫu nhiên của mã băm. – Roam

+1

nó sẽ là một định danh "xử lý" bất biến mà sẽ vẫn không đổi trong suốt vòng đời của đối tượng. Nhiều khả năng VM thực thi phụ thuộc và sẽ có khả năng không có bất kỳ mối quan hệ với địa chỉ bộ nhớ, bởi vì do hoạt động GC tất cả các đối tượng trong java là relocatable trong bộ nhớ vật lý. – peterk

11

Native hashCode phương pháp thực hiện phụ thuộc vào JVM. Theo mặc định trong HotSpot, nó trả về số ngẫu nhiên, bạn có thể kiểm tra nó trong số source code (chức năng get_next_hash)

+0

Thx cho liên kết thú vị. – Roam