Java:重复的对象被添加到set?

sno*_*ard 16 java hash hashcode hashset

如果我运行以下代码,则输出为2,这意味着该集合包含2个元素.但是我认为该集应该包含1,因为两个对象基于hashcode()值以及.equals()方法是相等的.在我的理解中似乎有些明显的错误?

package HELLO;

import java.util.HashSet;
import java.util.Set;

public class Test {

    public static void main(String[] args) throws Exception {
        Set<Alpha> s = new HashSet<Alpha>();
        Alpha a1 = new Alpha();
        Alpha a2 = new Alpha();
        s.add(a1);
        s.add(a2);
        System.out.println(s.size());
    }
}   

class Alpha {
    int a = 10;

    public int hashcode() {
        return a;
    }

    public boolean equals(Object obj) {
        return (obj instanceof Alpha && ((Alpha) obj).a == this.a);
    }

    public String toString() {
        return "Alpha : " + a;
    }
}
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 28

您的hash c ode方法不会覆盖Object类的hash C ode方法,因此您的equals方法会破坏契约,因为它与hashCode结果不一致,并且您可以拥有"相等"但具有不同hashCodes的对象.

请记住:@Override在覆盖方法时应始终使用注释,因为这将帮助您捕获此类错误.

@Override  // ** don't forget this annotation
public int hashCode() { // *** note capitalization of the "C"
  return a;
}
Run Code Online (Sandbox Code Playgroud)

此外,您还需要改进代码格式,尤其是在此处发布代码以供我们审核时.如果符合标准(这就是标准存在的原因),我们将能够更好地理解您的代码并为您提供帮助.因此,请尝试使缩进与同一块中同一块中缩进的所有代码行保持一致,并且您需要确保基本级代码(包括导入,外部类声明及其结束大括号)是向左刷新的:

import java.util.HashSet;
import java.util.Set;

public class Test {

   public static void main(String[] args) throws Exception {
      Set<Alpha> s = new HashSet<Alpha>();
      Alpha a1 = new Alpha();
      Alpha a2 = new Alpha();
      s.add(a1);
      s.add(a2);
      System.out.println(s.size());
   }
}

class Alpha {
   int a = 10;

   @Override
   public int hashCode() {
      return a;
   }

   public String toString() {
      return "Alpha : " + a;
   }

   @Override
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      Alpha other = (Alpha) obj;
      if (a != other.a)
         return false;
      return true;
   }
}
Run Code Online (Sandbox Code Playgroud)

有关这方面的精彩评论,请阅读:覆盖Java中的equals和hashCode

  • @hoverkraft:你是对的,我在 equals() 中遇到了错误,在错误的情况下返回了 false。,因此出现了多个条目。在 equals() 中检查哈希值是个坏主意。 (2认同)