Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird HashSet contains() behaviour

Tags:

java

contains

HashSet in java confused me a lot, when using contains() will it look up hashcode() and equals() result ? But in this case, it doesn't behave normal. Sometime it's problematic if you put this kind of code in large project. Problem is why last statement print FALSE ?what contains() do under the hood ?

class R
{
    int count;
    public R(int count)
    {
        this.count = count;
    }
    public String toString()
    {
        return "R(count attribution:" + count + ")";
    }
    public boolean equals(Object obj)
    {
        if (obj instanceof R)
        {
            R r = (R)obj;
            if (r.count == this.count)
            {
                return true;
            }
        }
        return false;
    }
    public int hashCode()
    {
        return this.count;
    }
}
public class TestHashSet2
{
    public static void main(String[] args) 
    {
        HashSet hs = new HashSet();
        hs.add(new R(5));
        hs.add(new R(-3));
        hs.add(new R(9));
        hs.add(new R(-2));

        System.out.println(hs);

        //change first element
        Iterator it = hs.iterator();
        R first = (R)it.next();
        first.count = -3;
        System.out.println(hs);
        //remove
        hs.remove(new R(-3));
        System.out.println(hs);

        R r1 = new R(-3);
        System.out.println(r1.hashCode());
        Iterator i = hs.iterator();
        R r2 = (R)i.next();
        System.out.println(r2.hashCode());   //same hashcode -3
        System.out.println(r1.equals(r2));   //equals true

        System.out.println("hs contains object which count=-3 ?" + hs.contains(new R(-3)));  //false
    }
}
like image 933
CodeFarmer Avatar asked Dec 21 '22 01:12

CodeFarmer


1 Answers

By changing an the value of an object after inserting it into the HashSet, you are destroying the integrity of the data structure. After that, you cannot rely on it doing its job.

It's generally a bad idea to use mutable objects as keys for any map or values for a set. Fortunately, the classes used most commonly for this purpose (String, Integer) are immutable.

like image 144
Michael Borgwardt Avatar answered Dec 23 '22 16:12

Michael Borgwardt