简体   繁体   中英

Simple HashSet contains misunderstanding

I don't understand why HashSet returns false for next example. Code:

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));
    }

}

Result:

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

Excerpt from HashSet contains method description:

Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).

Question: why does it return false for both objects even though they are both not null and they are both equal in terms of hesh and value?

Because you did'nt override the equals method herited from the Object class.

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

Output (demo here ):

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

You have an error with overriding Object's equals method.

    public boolean equals(Name n){

is just a method. The correct contract is:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM