HashSet contains()为自定义对象返回false。 hashCode()和equals()似乎正确实现

时间:2013-09-01 03:49:23

标签: java

我有以下简单的Rectangle类。如果两个矩形具有相同的高度和宽度,则它们相等并具有相同的哈希码。我在hashSet中添加了一个新的矩形。

Set<Rectangle> set = new HashSet<Rectangle>();
set.add(new Rectangle(3,3));

当我尝试在具有相同高度和宽度的新矩形上调用contains时,它返回false。

set.contains(new Rectangle(3,3))返回false。我无法弄清楚为什么。有什么想法吗?

   public class Rectangle implements Comparable<Rectangle> {
            final int height, width, area, minimumEdge, maximumEdge;

            public Rectangle(int height, int width) {
                this.height = height;
                this.width = width;
                area = height * width;
                maximumEdge = height > width ? height : width;
                minimumEdge = height < width ? height : width;
            }

            public int compareTo(Rectangle rect2) {
                if (rect2.minimumEdge > this.minimumEdge) {
                    return -1;
                } else if (rect2.minimumEdge < this.minimumEdge) {
                    return 1;
                } else {
                    return 0;
                }
            }

            public int hashCode(){
                return ((width + height)*31);
            }

            public boolean equals(Rectangle rect2){
                return (this.height == rect2.height && this.width == rect2.width);
            }
        }

2 个答案:

答案 0 :(得分:14)

您实际上没有覆盖equals()

您创建了一个新的equals(Rectangle)方法,该方法与虚拟equals(Object)方法无关。

这就是为什么在尝试覆盖方法时应始终添加@Override

答案 1 :(得分:3)

下面:

public boolean equals(Rectangle rect2){
            return (this.height == rect2.height && this.width == rect2.width);
        }

您可以创建自己的equals方法,而不是覆盖超类方法。

你必须写得像:

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Rectangle rect2 = (Rectangle) obj;
    return (this.height == rect2.height && this.width == rect2.width);
}