根据HashSet的JDK文档,remove():
删除元素e,使得(o == null?e == null:o.equals(e)),如果 这个集合包含这样一个元素。
嗯,这里有一小部分代码证明不是这样。 Set点肯定包含我的观点,如equals()所示,然而,remove()神秘地无法删除它。麻烦似乎是由于point.x的值的变化(main()的第4行)。省略这一点会使一切都按预期运行。
请注意,如果points是ArrayList而不是HashSet,则以下行为正常。
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.HashSet;
public class RemoveTest2 {
public static void main(final String[] args) {
final Collection<Point2D.Double> points = new HashSet<Point2D.Double>();
final Point2D.Double point = new Point2D.Double();
points.add(point);
point.x++;
// make sure that points definitely contains the point we are trying to remove...
for (final Point2D.Double p : points) {
if (point.equals(p)) {
System.out.println("points definitely contains " + point);
System.out.println(point.hashCode() + " == " + p.hashCode());
}
}
if (!points.remove(point)) {
System.out.println("and yet... failed to remove " + point);
}
System.out.println("points cointains " + points.size());
}
}
规范看起来很痛苦......请有人向我解释我在这里缺少的东西。
答案 0 :(得分:2)
问题是您在使用对象后更改了对象的哈希码,因此Hashset无法使用新的哈希码获取现有对象(因为它使用旧的哈希码存储)。
更改此类字段时,您需要先删除此对象,然后再更改它,而不是再次存储它。
查看this