在使用我的应用程序时,我在尝试从java集合中删除对象时遇到了问题(使用EclipseLink从数据库中提取集合)。 我想要在具有覆盖等于方法的实体类中删除的对象。 我甚至用以下代码检查了集合中的任何对象是否是我要删除的对象:
for(AlbumEntity entity : deleteGroup.getAlbums()){
System.out.println("VAL: " + deleteAlbum.equals(entity));
}
在这种情况下,返回的值之一为true。但是,如果我这样做:
boolean result = deleteGroup.getAlbums().remove(deleteAlbum);
result
的值为false,并且集合的大小保持不变。
感谢您的提前帮助
编辑:
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof AlbumEntity)) {
return false;
}
AlbumEntity other = (AlbumEntity) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
答案 0 :(得分:5)
一些可能性:
1)id的equals或hashCode方法的实现存在问题。在这种情况下,您可以id1.equals(id2)
但id1.hashCode() != id2.hashCode()
。这会导致相册对象的equals和hashCode()之间的不一致,并可能导致您看到的症状。
2)一个或多个专辑的ID在for循环之后的某个时刻发生变化,该循环检查集合中每个专辑的deleteAlbum.equals(entity)
。如果相册的ID更改,则remove()方法may not be able to find it。如果保存到数据库,id可以从null更改为某个非null数 - 如果没有您明确要求,EclipseLink可能会为您执行此操作。
3)由于EclipseLink的干扰,当您运行代码时,deleteGroup实际上可能不是HashSet。 docs for EclipseLink建议它会给你一个“间接对象”,而不是你的类中声明的java.util.Set(或我假设的java.util.HashSet),具体取决于它的配置方式。在这种情况下,contains和remove方法可能无法达到预期效果。
有关这些以及涉及equals和hashCode的其他可能问题的更多详细信息,请参阅Overriding equals and hashCode in Java,这可能会导致使用集合的奇怪行为。
答案 1 :(得分:2)
好的,让我们尝试一下测试:
<强> 1 强>
Iterator<AlbumEntity> it = deleteGroup.getAlbums().iterator();
while(it.hasNext()){
AlbumEntity entity = it.next();
Assert.assertTrue(deleteGroup.getAlbums().contains(entity))
}
此测试是否成功运行?