先上代码,看看有没有类似的错误
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>