接上一篇《如何在Java中避免equals方法的隐藏陷阱(上)》
陷阱3:建立在会变化字段上的equals定义
让我们在Point类做一个非常微小的变化
public class Point { private int x; public Point(int x, int y) { public int getX() { public int getY() { public void setX(int x) { // Problematic public void setY(int y) { @Override public boolean equals(Object other) { @Override public int hashCode() { |
唯一的不同是x和y域不再是final,并且两个set方法被增加到类中来,并允许客户改变x和y的值。equals和hashCode这个方法的定义现在是基于在这两个会发生变化的域上,因此当他们的域的值改变时,结果也就跟着改变。因此一旦你将这个point对象放入到集合中你将会看到非常神奇的效果。
Point p = new Point(1, 2); HashSet<Point> coll = new HashSet<Point>(); System.out.println(coll.contains(p)); // 打印 true |
现在如果你改变p中的一个域,这个集合中还会包含point吗,我们将拭目以待。
p.setX(p.getX() + 1); System.out.println(coll.contains(p)); // (有可能)打印 false |