views:

584

answers:

4

I have MyClass, which stores two integers, and I have a Vector<MyClass> called myVector.

Now, I do this:

...
myVector.add(new MyClass(1,1));
for(MyClass m : myVector)
    System.out.println(m);
System.out.println(myVector.size());

myVector.remove(new MyClass(1,1));
for(MyClass m : myVector)
    System.out.println(m);
System.out.println(myVector.size());
...

The problem here is that the object isn't being removed, as I see when I print the Vector and its size. How could I fix that?

Edit: I can see that it isn't finding the object and I've tested with contains() to be sure. What I need is to compare it by value. If I could overload the == operator I could do it, but I have no idea how to fix this.

Edit 2: Okay, equals() will do what I want it to. But I'm not sure what to put in the hashCode method.

Edit 3: I can find it with contains(), but remove doesn't remove it.

I can use this to remove it though:

int position = myVector.indexOf(new MyClass(1,1));
myVector.remove(position);

Which is the same as remove(new MyClass(1,1), except the above code works and remove() doesn't. Any thoughts?

+1  A: 

You're trying to remove a different myClass, even though it contains the same values as the first one.

If you want them to be considered equal, you need to override the equals method for myClass to check that the values are equal.

Strilanc
and of course the hashcode method. Eclipse has a decent autogenerator for this.
JeeBee
A: 

You need to implement .equals() for those two objects to be considered ... well, equal. But keep in mind that the contract for .equals() and .hashCode() basically tells you that you have to implement .hashCode() whenever you implement .equals().

Chapter 3 of Effective Java will tell you more.

Joachim Sauer
+2  A: 

You have two choices:

  • implement equals() for MyClass, or
  • remove the same object instance you added

Your code modified to remove the same instance that you added:

MyClass myClass = new myClass(1,1);
myVector.add(myClass );
for(myClass m : myVector)
  System.out.println(m);
System.out.println(myVector.size());

myVector.remove(myClass );
for(myClass m : myVector)
  System.out.println(m);
System.out.println(myVector.size());

I see that others gave a sample implementation for equals() -- but you have to decide is that what you want? It very well may be. You get to pick which of the above two choices is right for this object.

As others said, if you implement equals() then you must implement hashCode(). Eclipse has a nice right-click option to implement both equals() and hashCode(). I have seen code problems where someone implemented only equals() so although this seems like a theoretical issue, it's really not.

Eddie
A: 

There are few errors in grammar31's answer; fix them up here:

@Override
public boolean equals(Object o) {
  if ((o == null) || (o.getClass() != myClass.class)) {
    return false;
  }
  myClass other = (myClass) o;
  return (other.a == this.a) && (other.b == this.b);
}

@Override
public int hashCode() {
  return a * 31 + b;
}

This assumes myClass has int members a and b.

erickson