如何在不出错的情况下覆盖哈希代码"long cannot be dereferenced"?


public class Card
{   
long id;
String name;
Rank rank;
long price;
public Card(long id, String name, Rank rank)
{
this.id = id;
this.name = name;
this.rank = rank;
this.price = 0;
}
public String toString()
{
return "id: " + this.id + "n" + "name: " + this.name + "n" + "rank: " + this.rank + "n" + "price: " + this.price;
}
public boolean equals(Card card)
{
if (this.id == card.id)
{
if (this.name.equals(card.name))
{
if (this.rank == card.rank)
{
return true;
}
}
}
return false;
}
public int hashCode()
{
return id.hashCode() + name.hashCode() + rank.hashCode();
}
}

我写了一个类卡,里面有id,name,price和rank,就是enum rank。

我正在尝试覆盖equals和hashCode。只有当id、名称和等级相同时,比较的两张牌才应被视为相等。

我得到"长不能被取消引用"。我不能只使用id本身,因为它很长时间都不是int。

首先,您的equals不正确。您不能更改Object.equals(Object)的签名。其次,long不是对象类型。所以,你不能对它调用hashCode(),但你可以把它传递给Long.hashCode(long)方法。最后,当您打算重写一个方法以防止第一类错误时,总是使用Override注释。比如

@Override
public boolean equals(Object o) {
if (o instanceof Card) {
Card card = (Card) o;
if (this.id == card.id) {
if (this.name.equals(card.name)) {
if (this.rank.equals(card.rank)) {
return true;
}
}
}
}
return false;
}
@Override
public int hashCode() {
return Long.hashCode(id) + name.hashCode() + rank.hashCode();
}

而不是

return id.hashCode() + name.hashCode() + rank.hashCode();

用途:

return Objects.hash(id, name, rank);

Objects.hash给出了比仅仅将数字相加更好的分布。此外,您不必担心null值或计算基元类型的哈希代码的正确方法。


注意,这涉及到将基元long自动装箱到包装类Long。它还创建了一个临时对象数组,因为hash是一个varargs方法。

long id更改为Long id。注意,Long是包装类,而long是基元类型。基元类型没有任何可调用的方法/函数。

不能直接在基元上调用方法,它们必须被装箱。请使用Long.valueOf(id).hashCode()Long.hashCode(id),而不是仅使用id.hashCode()。Java的基元与对象不同,尽管它在将基元传递给期望对象的方法时会自动装箱,反之亦然,但在这里它不能这样做。如果您愿意,请阅读此处的文档:https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

相关内容

最新更新