Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot remove or find an object in Java's CopyOnWriteArraySet

I use CopyOnWriteArraySet to store one instance of a custom class, which looks like this:

public class MyClass{
 String _name;

 public MyClass(String name){
  _name = name;
 }

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

 @Override
 public boolean equals(Object obj){
  if (obj == this) return true;
  if ((obj instanceof MyClass) == false) return false;
  MyClass otherObject = (MyClass) obj;
  return _name.equals(otherObject._name);
 }

 @Override
 public String toString(){
  return _name;
 }
}

When I print the set, everything seems ok:

MyClass theObject = new MyClass("Object 1");
CopyOnWriteArraySet<MyClass> theSet = new CopyOnWriteArraySet();
theSet.add(theObject);

for (MyClass tmp : theSet){
 System.out.println(tmp.toString());
}

The result is:

Object 1

So, obviously the object is in the set.

Now, I want to remove the object from the set:

theSet.remove(theObject);

Then I print the content of the set again. The result:

Object 1

Very weird. So, I tried this:

System.out.println(String.valueOf(theSet.contains(theObject)));

The result:

false

Obviously, the set cannot find theObject although it's there. So, I thought, there's something wrong with the equals() method. Thus, I changed the method overrides of equals() and hashCode() by adding a console print to the first line of each function:

 @Override
 public int hashCode(){
  System.out.println("hashCode() called");
  return _name.hashCode();
 }

 @Override
 public boolean equals(Object obj){
  System.out.println("equals() called");
  if (obj == this) return true;
  if ((obj instanceof MyClass) == false) return false;
  MyClass otherObject = (MyClass) obj;
  return _name.equals(otherObject.name);
 }

Then, I call again:

theSet.remove(theObject);

The result:

hashCode() called

So, the equals() method isn't called at all?

Can someone explain what's going on there?

I already tried to compare the hashCodes of theObject and the instance inside the set and they're both equal.

like image 394
Timo Ernst Avatar asked Jun 08 '11 13:06

Timo Ernst


1 Answers

Strange..i have tested your codes. And it works well in my environment. And the remove operation doesn't call hashCode() but call equals() instead. The jdk what i used is 1.6.0_23.

like image 199
lxl Avatar answered Sep 19 '22 17:09

lxl