3

If I take for example a HashSet<E>, and add objects to it, how does it check if the object's already there?

I have the following simple setup:

private class MyObject {
    String text;

    public MyObject(String text) {
        this.text = text;
    }

    @Override
    public boolean equals(Object o) {
        if (o != null && o instanceof MyObject) {
            return ((MyObject) o).text.equals(text);
        }

        return false;
    }

}

In my project I have many objects like this, but all initialized separately. I want to filter the doubles, by adding all to a Set, like this:

MyObject m1 = new MyObject("1");
MyObject m2 = new MyObject("1");
MyObject m3 = new MyObject("2");

System.out.println(m1.equals(m2)); //expected: true, result: true
System.out.println(m1.equals(m3)); //expected: false, result: false

Set<MyObject> myObjects = new HashSet<MyObject>();
myObjects.add(m1);
myObjects.add(m2);
myObjects.add(m3);

System.out.println(myObjects.size()); //expected: 2, result: 3

Set<String> stringList = new HashSet<String>();
stringList.add("1");
stringList.add("1");
stringList.add("2");
System.out.println(stringList.size()); //expected: 2, result: 2

How can I make it so that my myObjects set does not contain these doubles? So m1 and m2 are different instances, but have the same content so I only need m1.

Edit
Based on Mathias Schwarz's answer I've implemented the hashCode() function as follows:

@Override
        public int hashCode() {
            return text.hashCode();
        }

But how would I implement this method if I have a more complex class with multiple fields?

nhaarman
  • 98,571
  • 55
  • 246
  • 278
  • 1
    for two objects o1, o2, if o1.equals(o2), then they have to return the same hashCode, and your class MyObject does not ensure it. You have to implement the methode hashCode in your class – gefei Oct 12 '12 at 11:18

4 Answers4

7

HashSet determines whether two object are identical on the results of invoking equals and hashCode on the object. You must implement hashCode if you implement equals. If they are inconsistent, HashSet will not behave correctly... So the important thing is how those two methods are implemented on MyObject (which btw is really a class...).

Mathias Schwarz
  • 7,099
  • 23
  • 28
  • Ah that makes sense, and it works. I've implemented the `hashCode()` function to return `text.hashCode()`. But how would I implement this method if I have multiple fields in the `MyObject` class? – nhaarman Oct 12 '12 at 11:22
  • @Niek you must implement it so that it conforms to the hash code contract; see for example DVK's answer on [this question](http://stackoverflow.com/questions/2707541/why-should-i-override-hashcode-when-i-override-equals-method?rq=1). – Jesper Oct 12 '12 at 11:37
  • if `o1.equals(o2)` then it must be the case that `o1.hashCode() == o2.hashCode()` (but not necessarily the other way around... – Mathias Schwarz Oct 12 '12 at 11:56
2

If your using eclipse then Right Click --> Source --> Generate hashCode and Equals .If you what to know more about hash code and equals read this portion from Effective Java .

Emil
  • 13,577
  • 18
  • 69
  • 108
0

add the following to your class MyObject

public String hashCode() {
  return text.hashCode();
}

(I suppose that text is not null. If it may be null, you'd have to take that into acccoutn and void a NPE)

gefei
  • 18,922
  • 9
  • 50
  • 67