2

So i am trying to Override equals() so when i make a set of my objects it will function correctly.

Here is the code i'm working with (ignoring type safety for now)

@Override
public boolean equals(Object o) {
    MyClass myObject1 = (MyClass) o;
    MyClass myObject2 = (MyClass) this;
    if (myObject1.property == myObject2.property)
        return true;
    return false;
}

You can assume there's only one property and it's a primitive type like an int.

However if i add two of the same objects to a set, they both are added.

Ben Arnao
  • 153
  • 4
  • 14
  • 1
    I don't think you need `MyClass myObject2 = (MyClass) this;`. You can get rid of this line and use `myObject1.property == this.property` inside the if statement. – Eric Mar 06 '17 at 19:06

3 Answers3

4

This is because you violated Java requirement for overriding equals:

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

Without an implementation of hashCode that returns identical values for equal objects a hash set will generally treat objects with distinct hash codes as different, unless there is a hash collision.

Once you implement hashCode for your class, the problem will be solved.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Your classes have to override equals and hashCode

From the Set Documentation

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.

The Set interface places additional stipulations, beyond those inherited from the Collection interface, on the contracts of all constructors and on the contracts of the add, equals and hashCode methods.

to override these methods you can do this:

public class Person {
    private String name;
    private int age;
    // ...

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
            // if deriving: appendSuper(super.hashCode()).
            append(name).
            append(age).
            toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
       if (!(obj instanceof Person))
            return false;
        if (obj == this)
            return true;

        Person rhs = (Person) obj;
        return new EqualsBuilder().
            // if deriving: appendSuper(super.equals(obj)).
            append(name, rhs.name).
            append(age, rhs.age).
            isEquals();
    }
}

https://stackoverflow.com/a/27609/1754020

Community
  • 1
  • 1
Eddie Martinez
  • 13,582
  • 13
  • 81
  • 106
1

It would work fine if you implement the hashCode() method like below.

public int hashCode(){
    return this.property.hashCode();
  }

Please note it is mandatory to override hashcode method of object class when you overide equals method of object class.

During add method call of a given Set, hashCode method is called first - once they(like a telephone directory index) are same, equals method is checked.

Srikanth Balaji
  • 2,638
  • 4
  • 18
  • 31