关于java的HashSet类的一个“bug”

先上代码,看看有没有类似的错误

public class Practice{
  int id;
  public Practice(int id) {
    this.id = id;
  }

  public static void main(String[] args) throws InterruptedException {
    HashSet practices = new HashSet<>();
    Practice practice1 = new Practice(1);
    practices.add(practice1);
    System.out.println(practices.contains(practice1));
    practice1.setId(2);
    System.out.println(practices.contains(practice1));
    
  }
  
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Practice) {
      Practice practice = (Practice) obj;
      return practice.getId() == this.id;
    }
    return false;
  }
  
  @Override
  public int hashCode() {
    // TODO Auto-generated method stub
    return id;
  }

}

输出的结果分别为true,false

这是为什么呢?

因为本类的hashCode与他的id相关,当对象的id变化了之后,他的存储位置本来应该发生变化,却并未发生变化。所以根据变化之后的id找不到原来的对象

那怎么解决呢?为大家提供以下几种方法

1、将hashCode换成一个固定值,虽然效率比较低,但是可以保证正确性(因为equals是动态比较,是正确的)

2、将类的hashCode有关的数据类型均设置为不可改变的

3、如果你想根据一个不变的id快速找到与该id对应的对象,可以改用HashMap


你可能感兴趣的:(java)