无法在Java的CopyOnWriteArraySet中删除或查找对象

Tim*_*imo 6 java collections set

我使用CopyOnWriteArraySet来存储自定义类的一个实例,如下所示:

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;
 }
}
Run Code Online (Sandbox Code Playgroud)

当我打印套装时,一切似乎都可以:

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

for (MyClass tmp : theSet){
 System.out.println(tmp.toString());
}
Run Code Online (Sandbox Code Playgroud)

结果是:

对象1

所以,显然对象在集合中.

现在,我想从集合中删除对象:

theSet.remove(theObject);
Run Code Online (Sandbox Code Playgroud)

然后我再次打印该集的内容.结果:

对象1

很奇怪.所以,我试过这个:

System.out.println(String.valueOf(theSet.contains(theObject)));
Run Code Online (Sandbox Code Playgroud)

结果:

显然,theObject虽然它在那里但是找不到.所以,我想,这个equals()方法有问题.因此,我更改了方法覆盖equals()hashCode()通过向每个函数的第一行添加控制台打印:

 @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);
 }
Run Code Online (Sandbox Code Playgroud)

然后,我再次打电话:

theSet.remove(theObject);
Run Code Online (Sandbox Code Playgroud)

结果:

hashCode()调用

那么,该equals()方法根本不被调用?

有人可以解释那里发生了什么吗?

我已经尝试比较theObject集合中的hashCodes 和实例,它们都是相等的.

Tim*_*imo 0

我找到了问题的原因。

我正在使用 Hibernate,它创建了一个自己的 org.hibernate.collection.PersistentSet 实例,它取代了我的 CopyOnWriteArraySet!

.contains() 和 .remove() 不起作用的事实是 Hibernate 中的一个错误:http://opensource.atlassian.com/projects/hibernate/browse/HHH-3799

我的例子的解决方案是不重写.hashCode() 方法。

注意:这可能不是适合所有情况的最佳解决方案。对我来说,它确实有效。在上面的链接中,描述了几种解决方法。