Câu hỏi quan trọng là chìa khóa của bạn là gì. (Không có ý định chơi chữ.) Như những người khác đã chỉ ra, mục đích là để giảm thiểu số lượng va chạm băm. Nếu bạn có thể nhận được số lần va chạm băm bằng không, tức là hàm băm của bạn tạo ra một giá trị duy nhất cho mỗi khóa thực sự được truyền cho nó, bạn sẽ có một băm hoàn hảo.
Lưu ý rằng trong Java, hàm băm thực sự có hai bước: Đầu tiên, khóa được chạy thông qua hàm hashCode cho lớp của nó. Sau đó, chúng tôi tính giá trị chỉ mục vào bảng băm bằng cách lấy giá trị này modulo kích thước của bảng băm.
Tôi nghĩ rằng mọi người thảo luận về hàm băm hoàn hảo có xu hướng quên bước thứ hai đó. Ngay cả khi bạn đã viết hàm hashCode tạo ra một giá trị duy nhất cho mỗi khóa được chuyển đến nó, bạn vẫn có thể nhận được một băm hoàn toàn khủng khiếp nếu giá trị này modulo kích thước bảng băm không phải là duy nhất. Ví dụ, giả sử bạn có 100 khóa và hàm hashCode của bạn trả về các giá trị 1, 1001, 2001, 3001, 4001, 5001, ... 99001. Nếu bảng băm của bạn có 100.000 vị trí, đây sẽ là băm hoàn hảo. Mỗi phím đều có khe riêng. Nhưng nếu nó có 1000 slot, tất cả chúng đều băm vào cùng một slot. Nó sẽ là băm tồi tệ nhất có thể.
Vì vậy, hãy xem xét việc xây dựng hàm băm tốt. Lấy những trường hợp cực đoan. Giả sử rằng chìa khóa của bạn là một ngày. Bạn biết rằng tất cả các ngày sẽ là vào tháng Giêng cùng năm. Sau đó, sử dụng ngày trong tháng vì giá trị băm sẽ tốt như nó sẽ nhận được: mọi thứ sẽ băm thành một số nguyên duy nhất trong một phạm vi nhỏ. Mặt khác, nếu ngày của bạn là ngày đầu tiên của tháng trong nhiều năm và nhiều tháng, lấy ngày của tháng sẽ là một băm khủng khiếp, vì mọi khóa thực tế sẽ ánh xạ tới "1".
Điểm của tôi là nếu bạn thực sự muốn tối ưu hóa băm của mình, bạn cần biết bản chất của dữ liệu. Phạm vi giá trị thực tế mà bạn sẽ nhận được là bao nhiêu?
loại khóa của bạn là gì? – jjnguy
Đăng bài này dưới dạng nhận xét vì nó không thực sự trả lời câu hỏi của bạn. Nhưng nếu bạn đang sử dụng java.util.Hashtable, thì không. Sử dụng một java.util.HashMap thay vì –