为什么这个集合包含检查失败?

Why is this set containment check failing?

我正在阅读 Effective Java 第 3 版,我正在阅读第 10 项:覆盖时遵循 Equals 合同。

那里有一个我试图在我的机器上模拟的例子。下面是相同的代码。

public class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Point))
            return false;

        Point p = (Point)obj;
        return (x == p.x) && (y ==p.y);
    }

    // Use this for demonstration with AtomicPoint class.
    /*@Override
    public boolean equals(Object obj) {
        if(obj == null  || (obj.getClass() != getClass())) {
            return false;
        }

        Point p = (Point)obj;

        return p.x == x && p.y == y;
    }*/
}

public class AtomicPoint extends Point{
    private static final AtomicInteger counter = new AtomicInteger();

    public AtomicPoint(int x, int y) {
        super(x, y);
        counter.incrementAndGet();
    }

    public static int getCounter() {
        return counter.get();
    }

    private static Set<Point> sampleSet = new HashSet<>();

    public static void main(String[] args) {
        sampleSet.add(new Point(1,2));
        sampleSet.add(new Point(1,3));
        sampleSet.add(new Point(1,4));

        AtomicPoint ap = new AtomicPoint(1,3);

        // This should return true but its returning false
        System.out.println(sampleSet.contains(ap));
    }
}

正如您从 AtomicPoint class 中的评论中看到的那样,我对包含检查的判断是错误的,而 Joshua Bloch 指出这应该 return 正确。有人可以帮我吗?

要使用 HashSet<T>HashMap<T>,您需要覆盖 super class 的 hashCode() 方法。你应该在你的编辑器中自动生成 hashCode()equals() 方法(我建议你总是在每个 class 中使用它)。如果你想使用 TreeSet<T>TreeMap<T> 你将需要实现 ComparableComparator<T> 接口并覆盖它们的 compare()compareTo() 方法以使用它。