Java等于和具有非基本类型的hashCode

时间:2010-07-28 16:00:25

标签: java

我有一个有一些非原始成员的课。

class Relation {
 String name;
 Role roleFrom;
 Role roleTo;
}

class Role {
  RoleType roleType;
  String details;
}
class RoleType {
  String typeName;
  String details;
}

时,两个关系是相等的
  1. 名称相等
  2. 角色类型(由唯一typeName标识)对于Role成员(roleFrom和roleTo)是相等的
  3. 如何为课程equals撰写hashCodeRelation。使用Netbeans时,它只显示3个字段(nameroleFromroleTo)。是因为,不应该访问roleFrom和roleTo(roleType - > typeName)中的基元类型。或者,请显示实施。

    感谢。

4 个答案:

答案 0 :(得分:7)

在使用非基本类型的字段实施hashCode()equals()时,假设这些类型也正确实现了hashCode()equals()。所以转到其他类并在那里实现hashCode()equals()(再次使用IDE的自动生成功能)。

答案 1 :(得分:5)

当覆盖你的equals方法时,你应该非常小心,最好的办法,正如Joshua Bloch在“Effective Java”中指出的那样,除非它完全覆盖它绝对必要,使用从java.lang.Object继承的默认equals实现,每个对象只等于它自己。

我建议您查看以下链接,了解如何正确实施equalshashCode方法。最后一个链接向您展示了在具有非基本类型时如何实现这些方法,以及在处理继承时的注意事项。

答案 2 :(得分:0)

一个潜在的解决方案,假设你

  1. 您必须覆盖实现的等于
  2. 你想要懒惰
  3. 你不介意将hashcode()和equals()方法视为黑盒子
  4. 不介意在编译时使用额外的工具
  5. 尝试使用Lombok's有用的EqualsAndHashcode annotation来为您处理此问题。当然,您可能仍应阅读@StudiousJoseph在其答案中提到的链接,以便您了解如何编写正确的equals / hashcode方法,但这个工具可以帮助减轻自己编写这些方法的一些痛苦和陷阱。

    正如其他人所提到的那样,在你的情况下,如果你需要自定义等于行为,你至少需要在Relations类上使用那个注释或覆盖equals()/ hashcode(),也可能在你的Role和Roletype类上使用在他们身上。

    编辑:我刚刚注意到你正在使用Netbeans。如果您想尝试Lombok:http://wiki.netbeans.org/Lombok#IDE_support

    ,这可能是相关的

答案 3 :(得分:-1)

正如其他人所说,你需要为其他两个类实现equals / hashCode。举个例子:

class Relation {
  String name;
  Role roleFrom;
  Role roleTo;

  public int hashCode() {
    // Just a sample. super.hashCode() would probably be better
    return name.hashCode() & roleFrom.hashCode() | roleTo.hashCode();
  }

  public boolean equals(Object o) {
    if(!(o instanceof Relation)) return false;
    Relation other = (Relation)o;

    return name.equals(other.name)
      && roleFrom.equals(other.roleFrom)
      && roleTo.equals(other.roleTo);
  }
}

class Role {
  RoleType roleType;
  String details;

  public int hashCode() {
    // Just a sample. super.hashCode() would probably be better
    return roleType.hashCode();
  }

  public boolean equals(Object o) {
    if(!(o instanceof Role)) return false;
    Role other = (Role)o;

    return roleType.equals(other.roleType);
  }
}
class RoleType {
  String typeName;
  String details;

  public int hashCode() {
    // Just a sample. super.hashCode() would probably be better
    return typeName.hashCode();
  }

  public boolean equals(Object o) {
    if(!(o instanceof RoleType)) return false;
    RoleType other = (RoleType)o;

    return typeName.equals(other.typeName);
  }
}

关于if(!(o instanceof XYZWK)) return false;:对于equals方法,这基本上只是失败快速,没有生成(或需要try / catch){{{ 1}}。