Java 为什么我不能删除具有覆盖的对象

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

在集合测试中,我创建了一个名为Name的类,并重写了equals方法,如下所示

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;
}