2015-07-17 24 views
6

Tôi đã thực thi mã bên dưới và tìm thấy đầu ra là false.Phương thức HashSet contains()

import java.util.Set; 
import java.util.HashSet; 

public class Name { 
    private String first, last; 

    public Name(String first, String last) { 
     this.first = first; 
     this.last = last; 
    } 

    public boolean equals(Object o) { 
     if (!(o instanceof Name)) 
      return false; 
     Name n = (Name) o; 
     return n.first.equals(first) && n.last.equals(last); 
    } 

    public static void main(String[] args) { 
     Set<Name> s = new HashSet<Name>(); 
     s.add(new Name("Donald", "Duck")); 
     System.out.println(s.contains(new Name("Donald", "Duck"))); 
    } 
} 

Tôi muốn biết cách ứng xử và lý do tại sao sản lượng là false.

+8

Bạn chưa ghi đè 'hashCode'. –

Trả lời

5

Bạn cần ghi đè phương pháp hashCode() cùng với equals(). Cả hai phương pháp được sử dụng cho các chức năng thích hợp của HashSet, vì vậy phải được overriden trong một người dùng định nghĩa lớp nếu bạn đang làm mà class như một key, khác hashCode() của Object lớp được làm quen và không có hai khác nhau objects có thể được coi như giống như hashCode() của chúng sẽ luôn khác nhau và chắc chắn sẽ trả lại false luôn trong trường hợp .

+0

@babanna nếu nó xóa những nghi ngờ của bạn, bạn có thể đánh dấu nó là chính xác. –

3

Để cho một HashSet (hoặc HashMap, cho vấn đề đó) để định vị đúng đối tượng của bạn, bạn cần ghi đè phương thức hashCode() sao cho hai đối tượng bằng nhau có cùng hashCode. Cách kinh điển để làm điều này trông như thế này (giả sử firstlast không thể null, giống như phương pháp equals bạn giả:

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + first.hashCode(); 
    result = prime * result + last.hashCode(); 
} 
1

phương pháp equals() của bạn là ok, nhưng bạn đã bỏ lỡ để ghi đè hashCode() phương pháp, chỉ cần ghi đè Phương pháp hashCode(), nó sẽ hoạt động Và đừng quên bạn luôn cần phải ghi đè cả equals() and hashCode() hoặc không ai trong số chúng để có được hành vi chính xác.

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((first == null) ? 0 : first.hashCode()); 
    result = prime * result + ((last == null) ? 0 : last.hashCode()); 
    return result; 
} 
1

Bạn phải ghi đè hashCode() trong mỗi lớp ghi đè equals(). Việc không làm như vậy sẽ dẫn đến vi phạm hợp đồng chung cho Object.hashCode(), điều này sẽ ngăn không cho lớp của bạn hoạt động bình thường cùng với tất cả các bộ sưu tập dựa trên băm, bao gồm HashMap, HashSet, and Hashtable.

từ Java hiệu quả, bởi Joshua Bloch

+0

đặt ở định dạng mã cung cấp bốn dấu cách cho mỗi dòng mã – jsroyal

2

Bất kỳ Hash dựa cấu trúc dữ liệu thực hiện (bộ sưu tập) trong Java kiểm tra sự trùng lặp dựa trên hai yếu tố:

1: nếu equals phương thức trả về true cho bất kỳ các yếu tố đã được lưu trữ trong bộ sưu tập.

2: nếu phương thức hashCode trả về same integer value cho bất kỳ phần tử nào đã được lưu trữ trong bộ sưu tập. Vì vậy, trong trường hợp của bạn, bạn đã không ghi đè phương thức hashCode, điều đó có nghĩa là nó sẽ cố gắng kiểm tra sự bình đẳng hashCode bằng cách sử dụng phương thức hashCode mặc định là Object mà không biết các biến số lastfirst của bạn.

Tôi hy vọng điều đó sẽ hữu ích.

0

Bạn cũng có thể xem mã của bạn sẽ được thực thi như thế nào.

  1. Khi bạn cố gắng thêm phần tử trong tập hợp, mã gọi là mã băm và mã được lấy.

  2. Khi bạn nhận được giá trị băm từ mã băm, giá trị ghi đè sẽ được chạy cho tất cả những người có cùng mã thông báo băm.

Hy vọng điều này sẽ hữu ích.

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