Java 为什么我不能删除具有覆盖的对象
在集合测试中,我创建了一个名为Name的类,并重写了equals方法,如下所示Java 为什么我不能删除具有覆盖的对象,java,Java,在集合测试中,我创建了一个名为Name的类,并重写了equals方法,如下所示 class Name implements Comparable<Name>{ private String firstName, lastName; Name(String firstName, String lastName){ this.firstName = firstName; this.lastName = lastName; } public String getFirs
class Name implements Comparable<Name>{
private String firstName, lastName;
Name(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public String toString(){
return firstName + " "+lastName;
}
public boolean equals(Name name){
return firstName.equals(name.firstName) && lastName.equals(name.lastName);
}
public int hashCode(){
return firstName.hashCode();
}
有一条评论和一个回答说您的
hashCode()
方法与equals()
不一致,因为您没有在哈希代码计算中包含lastName
。他们都错了
允许hashCode()
实现使用equals()
使用的值的子集。这样会导致更多的哈希代码冲突,抵消了hashcode()
速度的提高和哈希桶性能的下降。一个子集hashcode可能是正常的,这取决于Name
对象具有相同firstName
的可能性
您的问题是equals()
的签名错误。它必须是布尔等于(对象)
boolean equals(Name)
不是对boolean equals(Object)
的重写,因此您实际上没有重写/实现equals()
方法,因此导致hashCode()
与equals()
不一致(但不是因为其他人所说的原因)
如果添加@Override
注释,编译器将发现此问题。始终使用注释
改为:
@Override
public boolean equals(Object obj) {
if (! (obj instanceOf Name))
return false;
Name that = (Name)obj;
return this.firstName.equals(that.firstName) && this.lastName.equals(that.lastName);
}
@Override
public int hashCode() {
return this.firstName.hashCode();
}
当然,这假设两者都不能为null
正如@MickMnemonic在评论中所说: 省略包含在
equals()中的字段被认为是不好的做法。
要在计算中包括lastName
,请使用:
此外,如@StephenB:
您还需要添加一个
compareTo
方法,因为您正在实现Comparable
这里使用名称
作为参数,而不是对象
,因为Comparable
的泛型类型参数
示例(如果按姓氏前的名字排序):
实现firstName/lastName的。您可能希望使用或可能使用来进行正确的本地化排序。那么您的意思是我需要重写lastName hashcode()?您还需要添加一个
compareTo
方法,因为您正在实现Comparable
正确和良好的捕获。但是,在计算hashCode()
时,忽略包含在equals()
中的字段被认为是不好的做法,因此我会在其中添加lastName
(并使用Objects.hash(…)
)。@MickMnemonic True。补充回答。谢谢。我已经删除了我的答案,因为编辑它与您的答案相比不会增加足够的值。“这当然假设两者都不能为null。”这是一个不安全的假设,因为类不抵抗null
值。谢谢。如果我想在这个类中使用泛型,如何重写equals()方法?我的意思是我不想用“instanceOf”
@Override
public boolean equals(Object obj) {
if (! (obj instanceOf Name))
return false;
Name that = (Name)obj;
return this.firstName.equals(that.firstName) && this.lastName.equals(that.lastName);
}
@Override
public int hashCode() {
return this.firstName.hashCode();
}
@Override
public int hashCode() {
return Objects.hash(this.firstName, this.lastName);
}
@Override
public int compareTo(Name that) {
int cmp = this.firstName.compareTo(that.firstName);
if (cmp == 0)
cmp = this.lastName.compareTo(that.lastName);
return cmp;
}