[Tại thời điểm viết bài này, ba câu trả lời khác đã được đăng.]
Để nhắc lại, mục đích của câu hỏi của tôi là tìm ra các trường hợp kiểm tra tiêu chuẩn để xác nhận điều đó hashCode
và equals
đồng ý với nhau. Cách tiếp cận của tôi đối với câu hỏi này là tưởng tượng ra các con đường phổ biến mà các lập trình viên thực hiện khi viết các lớp được đề cập, cụ thể là dữ liệu bất biến. Ví dụ:
- Viết
equals()
mà không viết hashCode()
. Điều này thường có nghĩa là bình đẳng được định nghĩa có nghĩa là bình đẳng của các trường của hai trường hợp.
- Viết
hashCode()
mà không viết equals()
. Điều này có thể có nghĩa là lập trình viên đang tìm kiếm một thuật toán băm hiệu quả hơn.
Trong trường hợp số 2, vấn đề dường như không tồn tại đối với tôi. Không có trường hợp bổ sung nào được thực hiện equals()
, vì vậy không yêu cầu trường hợp bổ sung nào có mã băm bằng nhau. Tệ nhất, thuật toán băm có thể mang lại hiệu suất kém hơn cho các bản đồ băm, nằm ngoài phạm vi của câu hỏi này.
Trong trường hợp # 1, kiểm tra đơn vị tiêu chuẩn đòi hỏi phải tạo ra hai phiên bản của cùng một đối tượng với cùng một dữ liệu được truyền cho hàm tạo và xác minh các mã băm bằng nhau. Điều gì về dương tính giả? Có thể chọn các tham số hàm tạo chỉ xảy ra để mang lại các mã băm bằng nhau trên một thuật toán không liên kết. Một bài kiểm tra đơn vị có xu hướng tránh các tham số như vậy sẽ đáp ứng tinh thần của câu hỏi này. Cách tắt ở đây là kiểm tra mã nguồn equals()
, suy nghĩ kỹ và viết một bài kiểm tra dựa trên đó, nhưng mặc dù điều này có thể cần thiết trong một số trường hợp, nhưng cũng có thể có những bài kiểm tra phổ biến bắt gặp các vấn đề chung - và những bài kiểm tra như vậy cũng đáp ứng tinh thần của câu hỏi này.
Ví dụ: nếu lớp được kiểm tra (gọi nó là Dữ liệu) có một phương thức khởi tạo nhận một Chuỗi và các cá thể được xây dựng từ Chuỗi là các equals()
cá thể được sinh ra đã có equals()
, thì một bài kiểm tra tốt có thể sẽ kiểm tra:
new Data("foo")
- khác
new Data("foo")
Chúng tôi thậm chí có thể kiểm tra mã băm new Data(new String("foo"))
để buộc Chuỗi không bị xen vào, mặc dù điều đó có nhiều khả năng mang lại mã băm chính xác hơn Data.equals()
là mang lại kết quả chính xác, theo ý kiến của tôi.
Câu trả lời của Eli Courtwright là một ví dụ về việc nghĩ ra cách phá vỡ thuật toán băm dựa trên kiến thức về equals
đặc điểm kỹ thuật. Ví dụ về một bộ sưu tập đặc biệt là một ví dụ hay, vì đôi khi những thứ do người dùng tạo xuất hiện Collection
và khá dễ bị sai sót trong thuật toán băm.