I have an object in a LinkedHashSet
that implements equals
, hashCode
and compareTo
(in a superclass) but when I try to remove that exact object from the set set.remove(obj)
the remove method returns false
and the object remains in the set. Is the implementation of LinkedHashSet
supposed to call the equals()
method of its objects? Because it doesn't. Could this be a java bug? I'm running 1.6.0_25.

- 39,912
- 17
- 102
- 155

- 2,545
- 3
- 23
- 21
-
4[First rule of programming: It's always your fault](http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html) Without seeing your code, we can't tell you what you're doing wrong. – Brian Roach Oct 26 '11 at 02:10
-
4Please hold a mirror up in front of your webcam so I can see your code. Oh, and reverse all the windows so I don't have to read it backwards. At this point I'm... skeptical it's a Java bug. – Dave Newton Oct 26 '11 at 02:11
-
Post here the code of `equals()` and `hashCode()` – Óscar López Oct 26 '11 at 02:11
-
Test `equals` on the object you are passing to remove and the object you think should be removed first. – Ray Toal Oct 26 '11 at 02:13
-
A `HashSet` removes an element if they are `equal()`. http://download.oracle.com/javase/6/docs/api/java/util/HashSet.html#remove(java.lang.Object) – tskuzzy Oct 26 '11 at 02:14
3 Answers
My guess would be that your object's hashCode()
implementation is returning a different value than when you added the object to the set.

- 36,219
- 10
- 45
- 60
-
1Which is why we're asking to see the code--not really an answer yet ;) – Dave Newton Oct 26 '11 at 02:14
-
@Dave well my reasoning is that mekazu says equals() isn't being called, which it wouldn't be if the object wasn't found by its hash due to the hash changing. – Stephen Denne Oct 26 '11 at 02:20
-
Not saying you're wrong, saying it's premature :) Could just be the object's state is changing, too--who knows. – Dave Newton Oct 26 '11 at 02:22
-
@mekazu in Oracle's 1.6.0_25 LinkedHashSet, both contains() and remove() end up mapping the hashCode() of the supplied object to an index in an array. The hash is compared to the hash of the entries found there, since multiple hashes can map to the same index, and if the hash is the same, then the equals method is called. If your objects are equal, they should return the same hashcode, as per the javadocs on hashCode() – Stephen Denne Oct 26 '11 at 02:32
-
Correct! The object key was added to the object after it was inserted into the Set. Thus hashCode returned a different value to when it was first added. It's strange that the [javadoc](http://download.oracle.com/javase/6/docs/api/java/util/HashSet.html#remove(java.lang.Object)) doesn't make mention of this caveat. – mekazu Oct 26 '11 at 02:38
-
1That 'caveat' is mentioned in the javadoc of hashCode() on Object: "[..] invoked on the same object more than once [..], the hashCode method must consistently return the same integer, [..]" – Mark Rotteveel Oct 26 '11 at 12:43
LinkedHashSet
works fine for me:
import java.util.*;
public class Test {
public static void main( String[] args ) {
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
String s = "hi";
lhs.add( s );
System.out.println( lhs );
lhs.remove( s );
System.out.println( lhs );
}
}
Perhaps you're passing in a reference to a different object to the remove method? Are you sure you didn't change the reference in any way?
Also make sure that hashCode()
returns the same value when you insert it as when you are trying to remove it.

- 35,812
- 14
- 73
- 140
-
2
-
He says he calls remove on "that exact object". So I assume he meant that exact reference (or lack thereof). – tskuzzy Oct 26 '11 at 02:15
The chances of this being a bug in LinkedHashSet
are infinitessimnally small. You should dismiss this as a plausible explanation of your problem.
Assuming that this is a bug in your code, then it could be due to a number of things. For instance:
- Your
equals
andhashCode
methods are returning contradictory answers for the object. - Your
equals
orhashCode
methods depend on mutable fields and those fields are being changed while the object is in the set. (For instance, if the hashcode value changes, the object is likely to be on the wrong hash chain, causing theremove
method to not find it.) - You have declared the
equals
method as an overload, not an override ofequals(Object)
. (That could explain why yourequals
is not being called ... assuming that your assertion is factually correct.) - The object you are trying to remove is (in reality) not the one you inserted.
- Something else has already removed the object.
- You are running a different version of some class that does not match the source code you have been examining.
Now, I know that you have dismissed some of these explanations. But that may have been premature. Review the evidence that you based that dismissal on.
Another approach you could use is to use a Java debugger to forensically examine the data structures (e.g. the innards of the LinkedHashSet
) and single-step the code where the deletion is supposed to be happening.

- 698,415
- 94
- 811
- 1,216