简单的HashSet包含误解

时间:2013-11-28 12:48:17

标签: java set hashset

我不明白为什么HashSet在下一个例子中返回false。代码:

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包含方法说明:

  

如果此set包含指定的元素,则返回true。更多   形式上,当且仅当此集合包含元素e时才返回true   这样(o == null?e == null:o.equals(e))。

问题:为什么它对两个对象都返回false,即使它们都不为空且它们在hesh和value方面都是相等的?

2 个答案:

答案 0 :(得分:8)

因为您没有覆盖从equals类继承的Object方法。

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

输出(演示here):

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

答案 1 :(得分:3)

重写Object的equals方法时出错。

    public boolean equals(Name n){

只是一种方法。正确的合同是:

    public boolean equals(Object o){
     // .....
    }