• Post Reply Bookmark Topic Watch Topic
  • New Topic

removeAll() working only some of the time.  RSS feed

 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a method do remove a specific element from a list. It iterates through a list and when it finds the one I want to eliminate, it adds that element to another list (in this example, ArrayList deadVampires. Sometimes it removes the element, sometimes it does not.
Here is the code (the prints are just so I can follow the array content before and after using removeAll().:




The output after a play or two shows my dilema:



See how @8a20 did not get removed..
 
Paul Clapham
Sheriff
Posts: 22823
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My guess is that there's something wrong with the equals() method in your Vampire class. That's what gets used by the removeAll() method to decide which objects to remove. So could you show us that method?
 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes, I have it set to make two vampires equal if their coordinates are equal...

 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The reason is that I want to identify a vampire to be eliminated by it's location on a grid....
 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
With that said...taking it out seems to make it work... thank you!
 
Paul Clapham
Sheriff
Posts: 22823
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ted Schrey wrote:I have it set to make two vampires equal if their coordinates are equal...


Yeah, that doesn't sound like a good idea to me either. Having said that I don't know what you should use instead, but as long as object identity (which is what you have when you remove the equals() method) is working for you, you might as well keep it that way.
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This still doesn't make sense. The only reason I can see that the killVampire() method would not work, is because Vampire's equals() method is not reflexive.

Do you have Vampire subclasses? What is the actual type of vamps?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:The only reason I can see that the killVampire() method would not work, is because Vampire's equals() method is not reflexive.

@Ted: which it might not be. The very first check of an equals() method should always be an identity check, viz:
HIH

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not true. The identity check is usually just a performance booster for objects with expensive comparisons. An object will *always* be equal to itself, regardless of an identity check, otherwise the symmetricity requirement will probably also fail.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Not true.
Right again. Jeez, I need another coffee...

The identity check is usually just a performance booster for objects with expensive comparisons...

But there I disagree. It is required (or certainly advisable) if you use super.equals() because of the way Object.equals() is implemented.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7969
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:It is absolutely required if you use super.equals() because of the way Object.equals() is implemented.



Can you give me an example where you would use super.equals()? As far as I know, you can not override equals() meaningfully more than once (overriding Object.equals()), without breaking transitivity. This is the reason why you should make an implementation of equals() final, unless you allow sub-types to improve performance.

[Edit]

Nevermind, you can do this as long as you use getClass() instead of instanceof. I'm still not convinced you need to compare for identity first though.
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ted Schrey wrote: . . . make two vampires equal if their coordinates are equal...
. . .
Please confirm that your Vampire class is final, or at least has no subclasses.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This current discussion, regarding reflexivity, I assume stems from the belief that the same object is being compared? And I assume it is based on the fact that the print out has the same hashcode?

How do we know that the same object is being compared? The OP overridden the hashCode() method, and although complete code was not shown, probably didn't override the toString() method. These could be different objects with the same hash code.


If I had to speculate on the issue, I would say that the OP probably declared the row and col variables as Integer references. This way, they could fail to be equal (as it is a reference comparison), and yet, the hashCode() method would still work (due to autoboxing).

[EDIT: in reading again, the OP did mention that it started working when the equals() method was removed... so, my speculation is likely wrong ... ]

Henry

 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What happens if you use the removeIf method?
 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, I've missed a few days.. anyway, Vampire has no sub-classes. It implements Creature Interface but is final.

Creature Interface:


Vampire Object:


But I do have to say, taking out the override equals() worked...
 
Campbell Ritchie
Marshal
Posts: 56529
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In that case the equals method was incorrectly overridden beforehand.

You need to decide what to do with your equals method, which means you start by deciding under which circumstances two objects are “equal” to each other. In some cases and maybe this is such an instance, all objects of a class are implicitly different from one another.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!