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

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

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

  public static void main(String[] args) throws InterruptedException {
    HashSet<Practice> 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<id,Object>


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值