3

How does the contains-method find out if a certain object is/is not in a HashSet? I created a class with two instance variables. Then I put a few instances into a HashSet. I created the same instances again (with same instance variable values) and used them as the input for the contains-method. Although it were the same objects, "contains" returned false every time. So, I'm wondering if only the references are checked, or the values of the objects. If I have to identical objects and I put one into the HashSet and call the the "contains" method with the other object will the method return true or false? If false, what do I have to do, so that it returns true?

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
cobby
  • 484
  • 3
  • 18
  • what language is that? Java? – njzk2 Aug 08 '15 at 00:28
  • 2
    The doc tells you the contract for `contains` in the specific case of the hash set. It tells you how it considers that 2 objects are the same key. – njzk2 Aug 08 '15 at 00:32
  • Oh yeah, sorry. It's JAVA.. – cobby Aug 08 '15 at 00:34
  • 2
    If you store instances of your custom class in a `HashSet` (or any `Set`), make sure you correctly override the `equals` and `hashCode` methods in that class. Otherwise, two objects in the `Set` are only considered equal if they are the same object (`==`). – Mick Mnemonic Aug 08 '15 at 00:47
  • 1
    possible duplicate of [What issues should be considered when overriding equals and hashCode in Java?](http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java) – user207421 Aug 08 '15 at 01:52
  • possible duplicate of [HashSet contains() method](http://stackoverflow.com/questions/31470515/hashset-contains-method) – durron597 Aug 10 '15 at 06:11

1 Answers1

4

Whether multiple objects will match when they are identical depends on how equals() and hashCode() are implemented. For example for class A every object is the same since it has only one final field set to a constant.

public static class A {
    final int a=2;
}

But the HashSet see containing one as containing the other:

 A a1 = new A();
 HashSet<A> hsA = new HashSet<>();
 hsA.add(a1);
 A a2 = new A();
 System.out.println("hsA.contains(a2) = " + hsA.contains(a2));

Class B is the same but overrides hashCode() and equals():

public static class B {

    final int a = 2;

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 17 * hash + this.a;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final B other = (B) obj;
        if (this.a != other.a) {
            return false;
        }
        return true;
    }

}

Running almost the same code:

    B b1 = new B();
    HashSet<B> hsB = new HashSet<>();
    hsB.add(b1);
    B b2 = new B();
    System.out.println("hsB.contains(b2) = " + hsB.contains(b2));

produces a different value. The output is :

hsA.contains(a2) = false
hsB.contains(b2) = true

Most IDE's have an option to generate hashCode() and equals() so that whether objects match can depend on exactly the fields you specify.

WillShackleford
  • 6,918
  • 2
  • 17
  • 33