2013-11-28 2 views
1

Я не понимаю, почему HashSet возвращает false для следующего примера. Код:Simple HashSet содержит недоразумение

import java.util.*; 

public class Name { 
    private String first, last; 

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

    public boolean equals(Name n){ 
     return n.first.equals(first) && n.last.equals(last); 
    } 

    public int hashCode(){ 
     return 31*first.hashCode()+last.hashCode(); 
    } 

    public static void main(String[] args){ 
     Set<Name> s = new HashSet<Name>(); 
     Name n1 = new Name("Donald", "Duck"); 
     Name n2 = new Name("Donald", "Duck"); 
     s.add(n1); 

     System.out.print("HashCodes equal: "); 
     System.out.println(n1.hashCode() == n2.hashCode()); 
     System.out.print("Objects equal: "); 
     System.out.println(n1.equals(n2)); 

     System.out.print("HashSet contains n1: "); 
     System.out.println(s.contains(n1)); 

     System.out.print("HashSet contains n2: "); 
     System.out.println(s.contains(n2)); 
    } 

} 

Результат:

HashCodes equal: true 
Objects equal: true 
HashSet contains n1: true 
HashSet contains n2: false 

Отрывок из HashSet содержит описание метода:

возвращает истину, если этот набор содержит указанный элемент. Далее формально возвращает true тогда и только тогда, когда этот набор содержит элемент e такой, что (o == null? E == null: o.equals (e)).

Вопрос: почему он возвращает false для обоих объектов, хотя оба они не равны нулю, и оба они равны по величине хеш и значение?

ответ

8

Потому что вы не переопределили метод equals, выделенный из класса Object.

@Override 
    public boolean equals(Object o){ 
     Name n = (Name)o; 
     return n.first.equals(first) && n.last.equals(last); 
    } 

Output (демо here):

HashCodes equal: true 
Objects equal: true 
HashSet contains n1: true 
HashSet contains n2: true 
+0

Да, легко проверить, что использование: n1.equals ((Object) n2). Благодаря! –

3

У вас есть ошибка с наиважнейшей объекта составляет метод.

public boolean equals(Name n){ 

- всего лишь метод. Правильный контракт:

public boolean equals(Object o){ 
    // ..... 
    } 
Смежные вопросы