Hind Forsum
Hind Forsum

Reputation: 10527

Java HashSet using customized class as key: "contains()" function always return false

I'm trying to use HashSet, while using my own class "Inner" as key type, as below:

import java.util.HashSet;
class Inner {
    int i;
    String s;
    public Inner(int i, String s) {
        this.i = i;
        this.s = s;
    }
    @Override
    public int hashCode() {
        return super.hashCode();
    }
    @Override
    public boolean equals(Object o) {
        Inner inner = (Inner) o;
        return i == inner.i && s.equals(inner.s);
    }
}

public class testEquals {
    public static void main(String [] args) {
        HashSet<Inner> hi = new HashSet<>();
        hi.add(new Inner(1,"abc"));
        System.out.println(hi.contains(new Inner(1,"abc")));
    }
}

It prints "false"

(1) My question is, as long as I try to use "contains" function, I have to construct a new object from "Inner" class to query, but because it's a new object, hashcode() is different. So I always get a "false" for "contains" functions.

(2) If I change the hashCode() to return "true" like equals when values are the same, then in other scenarios, different objects references are considered as "==" just like one unique reference.

(1) and (2) seems to conflict.

How to solve this?

Thanks!

Upvotes: 3

Views: 424

Answers (2)

Naresh Sharma
Naresh Sharma

Reputation: 101

  1. You have to overide hashCode() correctly without breaking the equals - hashcode contract.

The contract between equals() and hashCode() is:

  1. If two objects are equal, then they must have the same hash code.
  2. If two objects have the same hash code, they may or may not be equal.
  1. hashCode() does not returns true, it returns an int value. So just make sure it returns same int value for 2 different objects whose equals() return true.

Upvotes: 4

Eran
Eran

Reputation: 394106

You should override hashCode in a way that two equal objects will have the same hashCode.

For example:

@Override
public int hashCode() {
    return Objects.hash(i,s);
}

I'm not sure what's your problem with (2). If two objects are equal according to equals(), the HashSet should treat them as identical objects, even if they are not.

If, one the other hand, you wish the HashSet to treat any Inner instance as unique (regardless of the values of its instance variables), simply don't override hashCode and equals. However, it is rarely useful to use HashSet without overriding these methods.

Upvotes: 4

Related Questions