Một số lớp JVM chính (chẳng hạn như String hoặc List implementations) thực hiện bằng bằng cách trả lại Σ 31^n * field_n.hashCode()
cho mỗi field_n
có liên quan cho phương pháp equals
. Bên cạnh đó, cách tiếp cận này được đề xuất bởi Joshua Bloch trong Java hiệu quả (mục 9).Chiến lược triển khai hashCode
Tuy nhiên, các lớp khác như Map.Entry
implementations tuân theo các quy tắc khác nhau. Ví dụ, các tài liệu Map.Entry khẳng định rằng mã hash của một Map.Entry
nên
(e.getKey()==null ? 0 : e.getKey().hashCode())^
(e.getValue()==null ? 0 : e.getValue().hashCode())
này đôi khi có thể không thực tế để sử dụng trong các bảng băm, vì:
- mã băm của tất cả các mục có cùng khóa và giá trị là 0,
- hai mục e1 và e2 sao cho e1.key = e2.value và e1.value = e2.key có cùng mã băm.
Tại sao Java chọn đặc tả triển khai này cho Map.Entry
hashCode thay vì, ví dụ: 31 * (e.getKey()==null ? 0 : e.getKey().hashCode()) + (e.getValue()==null ? 0 : e.getValue().hashCode())
?
Sửa 1:
Để giúp tìm ra các vấn đề, đây là một ví dụ về mã hữu ích mà kết quả có hiệu suất rất kém do va chạm băm nếu nhiều mục có cùng một giá trị quan trọng và.
Phương pháp này tính toán tần suất của các mục nhập của các bản đồ khác nhau (sử dụng Multiset của Guava).
public static <K, V> Multiset<Map.Entry<K, V>> computeEntryCounts(
Iterable<Map<K, V>> maps) {
ImmutableMultiset.Builder<Map.Entry<K, V>> result = ImmutableMultiset.builder();
for (Map<K, V> map : maps) {
for (Map.Entry<K, V> entry : map.entrySet()) {
result.add(entry);
}
}
return result.build();
}
Việc triển khai của bạn không ảnh hưởng đến đầu ra cho khóa và giá trị là ** null **. Ngoài ra, không có nhiều hơn ** một mục nhập ** với một khóa trong Bản đồ bằng Java, một khóa chỉ xảy ra ** một lần ** trong bất kỳ việc triển khai Bản đồ nào. –
Tôi biết, tôi đã giả định rằng các khóa của HashMap là các thể hiện của Map.Entry. Điều này có thể xảy ra nếu bạn muốn tính tổng số cho mỗi mục nhập khóa-giá trị trên một số Maps. – jpountz
Tôi không thể thấy điều này sẽ ảnh hưởng đến trường hợp này, trừ khi bạn muốn đặt tất cả Map.Entry từ tất cả các bản đồ bên trong một bản đồ duy nhất để đếm chúng, nhưng điều này rõ ràng là sai. –