2009-12-24 68 views

Trả lời

7

Java không tạo hashCode(), tức là không có gì tự động xảy ra ở đây. Tuy nhiên, Object tạo ra một HashCode dựa trên địa chỉ bộ nhớ của cá thể của đối tượng. Hầu hết các lớp (đặc biệt nếu bạn định sử dụng nó trong bất kỳ API Collection) nào nên triển khai HashCode của riêng chúng (và theo hợp đồng phương thức bằng của riêng chúng).

+0

Từ file Object.java '(Đây là ** ** thường được thực hiện bằng cách chuyển đổi địa chỉ ** nội ** của đối tượng vào một số nguyên, nhưng việc thực hiện này kỹ thuật ** không ** được yêu cầu bởi ngôn ngữ lập trình Java TM.) '- nhấn mạnh của tôi. –

+0

Mã băm này có trả về giá trị khác sau khi đối tượng được di chuyển khi GC xảy ra không? – Jacky

+2

Ý tưởng rằng hashCode sử dụng địa chỉ bộ nhớ là một vật phẩm lịch sử http://stackoverflow.com/questions/36236615/does-object-tostring-or-object-hashcode-ever-give-the-memory-address-of-the -obje – Raedwald

23

hashCode() của Object thực sự là một phương pháp gốc và việc triển khai thực sự không phải là Java thuần túy. Bây giờ, về cách thức hoạt động, this answer from Tom Hawtin làm một công việc tuyệt vời tại giải thích nó:

Nhiều người sẽ cho rằng Object.hashCode sẽ trả lại địa chỉ của người đại diện đối tượng trong bộ nhớ. Trong các hiện thực hiện đại, các đối tượng thực sự di chuyển trong bộ nhớ. Thay vào đó, một khu vực của tiêu đề đối tượng được sử dụng để lưu trữ giá trị, có thể được bắt nguồn từ địa chỉ bộ nhớ tại thời điểm giá trị được yêu cầu đầu tiên.

Toàn bộ câu trả lời thực sự đáng để đọc.

5

Theo tài liệu API nền tảng Java, việc tính toán mã băm dựa trên địa chỉ JVM nội bộ 32 bit của đối tượng.

Đúng là đối tượng di chuyển trong khi thực thi (AFAIK lý do duy nhất là bộ thu gom rác). Nhưng hashcode không thay đổi.

Vì vậy, khi bạn có một đối tượng như thế này

Person person1 = new Person(); 
person1.setName("Alex"); 

Person person2 = new Person(); 
person2.setName("Alex"); 

Person person3 = person2; 

Trong trường hợp này person1.hashCode sẽ không được tính bằng person2.hashCode vì các địa chỉ bộ nhớ của hai đối tượng này là không giống nhau.

Nhưng person2.hashCode sẽ bằng với person3 vì chúng trỏ đến cùng một đối tượng.

Vì vậy, nếu bạn cần sử dụng phương thức hashCode cho các đối tượng của mình, bạn phải tự thực hiện nó.

Bằng cách thực hiện String.hashCode khác nhau. Nó là một cái gì đó như thế này: (C# cú pháp)

public int hashCode(String str) 
{ 
    int h = 0; 

    for (int i = 0; i < str.Length; i++) 
    h = (h * 31) + str[i]; 

    return h; 
} 

chỉnh sửa: Không kiểm tra tràn được thực hiện ở đây, vì vậy hashCode có thể là tích cực hay tiêu cực.

1

Java không tạo ra ý nghĩa hashCode cho bạn, đó là công việc của bạn với tư cách là một lập trình viên để tạo ra một hashCode hữu ích. Mặc định hashCode chỉ là vị trí bộ nhớ.

+3

Không chính xác - mã băm mặc định được dựa trên vị trí bộ nhớ * lần đầu tiên phương thức này được gọi là * cho đối tượng; xem câu trả lời của @ Pascal. –

+0

Điểm tốt, được ghi nhận hợp lệ. – fastcodejava

4

Object.hashCode() sử dụng System.identityHashCode() dựa trên số id cho một đối tượng cụ thể.

1

Hàm HashCode() có một số tùy chọn để tạo mã băm. Nó đặt tham số khởi động JVM.Chức năng, mà tạo hashCode() được viết trên C++, và bạn có thể xem mã here

  • HashCode == 0: Đơn giản chỉ cần trả về số ngẫu nhiên không có liên quan đến nơi trong bộ nhớ đối tượng được tìm thấy. Theo như tôi có thể thực hiện, số đọc toàn bộ của hạt giống không được tối ưu cho các hệ thống có nhiều bộ xử lý .
  • HashCode == 1: Đếm các giá trị mã băm, không chắc chắn giá trị nào chúng bắt đầu, nhưng có vẻ khá cao.
  • HashCode == 2: Luôn trả về mã băm nhận dạng giống hệt nhau 1. Điều này có thể được sử dụng để kiểm tra mã dựa trên nhận dạng đối tượng. Lý do tại sao JavaChampionTest trả về URL của Kirk trong ví dụ trên là tất cả các đối tượng đều trả lại mã băm giống nhau.
  • HashCode == 3: Đếm các giá trị mã băm, bắt đầu từ số không. Nó không phải là chủ đề an toàn, vì vậy nhiều luồng có thể tạo ra các đối tượng với cùng mã băm.
  • HashCode == 4: Điều này dường như có một số liên quan đến vị trí bộ nhớ mà tại đó đối tượng được tạo.
  • HashCode> = 5: Đây là thuật toán mặc định cho Java 8 và có hạt giống cho mỗi chủ đề . Nó sử dụng kế hoạch xor-shift của Marsaglia để tạo ra các số giả ngẫu nhiên .

Các thông tin được lấy từ here

+2

Câu trả lời cho câu hỏi của OP như thế nào? Đây có thể là một bình luận. – Mike

+0

Tại sao hồ sơ của tôi không phản hồi? –

+0

Đây là câu trả lời tốt hơn cho câu hỏi với bản chỉnh sửa mà bạn đã thêm vào. Quá xấu OP vẫn chọn một con đường khác. – Mike

Các vấn đề liên quan