我正在尝试为HashMap
创建自定义对象,并为hashcode
和equals
方法编写了代码。在HashMap
中添加对象时,equals
方法为true,hashcode
为两个对象返回相同的值,而HashMap
将两个对象添加为不同的对象。这怎么可能?
下面是我的代码:
class B {
String name;
int id;
public B(String name, int id)
{
this.name=name;
this.id=id;
}
public boolean equals(B b){
if(this==b)
return true;
if(b==null)
return false;
if(this.name.equals(b.name) && this.id==b.id)
return true;
else
return false;
}
public int hashcode(){
return this.id;
}
public String toString(){
return "name: "+name+" id: "+id;
}
}
为了测试以上代码,我在主类中添加了以下内容:
HashMap<B,String> sample=new HashMap<>();
B b1 = new B("Volga",1);
B b2 = new B("Volga",1);
System.out.println(b1.equals(b2));
System.out.println(b1.hashcode()+" "+b2.hashcode());
sample.put(b1, "wrog");
sample.put(b2,"wrog");
System.out.println(sample);
这将产生以下输出:
true
1 1
{name: Volga id: 1=wrog, name: Volga id: 1=wrog}
有人可以解释为什么会这样吗?
答案 0 :(得分:6)
您在这里遇到了两个问题:
可能有效的实现 如下所示:
class B {
String name;
int id;
public B(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public int hashCode() {
return this.id;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
B other = (B) obj;
if (id != other.id) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
@Override
public String toString() {
return "name: " + name + " id: " + id;
}
}
作为一般建议,请确保指定@Override
批注。然后,您的IDE和Java编译器(javac
)可以帮助您发现此类问题。
答案 1 :(得分:3)
实际上,由于打字错误(您使用的是hashCode
)和错误的用法,您既不会覆盖equals
的{{1}}也不是java.lang.Object
的{{1}}方法hashcode
方法中的参数。
对两者都有效的实际实现是:
equals
此实现实际上是由IntelliJ IDEA生成的。我真正喜欢这种实现的地方是,它使用@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
B b = (B) o;
return id == b.id &&
Objects.equals(name, b.name);
}
@Override
public int hashCode() {
return Objects.hash(name, id);
}
方法,大大简化了java.util.Objects.hash()
的生成,并且是Java 7中引入的。
答案 2 :(得分:1)
您必须覆盖 public ProductPriceMap()
{
Id(x => x.id);
Map(x => x.purchase_price);
Map(x => x.p_cur_code);
Map(x => x.p_rate);
Map(x => x.sale_price);
Map(x => x.s_cur_code);
Map(x => x.s_rate);
Map(x => x.quantity);
Map(x => x.deleted);
Map(x => x.create_date);
Map(x => x.update_date);
References(x => x.users, "id").ForeignKey("user_id").Cascade.None();
References(x => x.product, "id").ForeignKey("product_id").Cascade.None();
HasOne(x => x.product);
// HasMany(x => x.product).ForeignKeyConstraintName("price_id").Cascade.None();
// References(x => x.currency, "code").ForeignKey("p_cur_code").Cascade.None();
// References(x => x.currency, "code").ForeignKey("s_cur_code").Cascade.None();
Table("productprice");
}
和equals(Object)
方法,而不是hashCode()
和equals(B b)
。
尝试实现具有以下签名的方法,它应该可以工作:
hashcode()
您还可以使用IDE的自动生成功能来生成这些方法。这样,就不会有出错的机会。