代码之家  ›  专栏  ›  技术社区  ›  bsr

具有非原始类型的Java相等和哈希代码

  •  4
  • bsr  · 技术社区  · 14 年前

    我有一个非原始成员的班级。

    class Relation {
     String name;
     Role roleFrom;
     Role roleTo;
    }
    
    class Role {
      RoleType roleType;
      String details;
    }
    class RoleType {
      String typeName;
      String details;
    }
    

    两个关系是相等的,当

    1. 名字相等
    2. 角色成员(rolefrom和roleto)的角色类型(由唯一的typename标识)相等。

    如何写作 equals hashCode 上课 Relation . 当使用NetBeans时,它只显示3个字段( name , roleFrom roleTo )是因为,不应该访问rolefrom和roleto(roletype->typename)中的基元类型。或者,请显示一个实现。

    谢谢。

    4 回复  |  直到 14 年前
        1
  •  7
  •   Bozho    14 年前

    实施时 hashCode() equals() 对于非基元类型的字段,假定这些类型也实现 哈希德() 等式() 正确地。因此,转到其他类并实现 哈希德() 等式() 这里(再次使用您的IDE的自动生成功能)。

        2
  •  5
  •   Jose Diaz    14 年前

    当你超越你的 equals 方法,最好的方法,正如Joshua Bloch在 “有效Java” 完全不重写它,除非它是绝对必要的,使用从java.lang.object继承的默认equals实现,每个对象仅等于自身。

    我建议您检查以下链接,以了解如何适当地实现 等于 hashCode 方法。最后一个链接向您展示了当您有非基元类型时如何实现这些方法,以及在处理继承时的注意事项。

        3
  •  0
  •   whaley    14 年前

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

    1. 必须为实现重写Equals
    2. 你想偷懒
    3. 您不介意将hashcode()和equals()方法视为黑盒
    4. 不要介意在编译时使用额外的工具

    是尝试使用 Lombok's 有用的 EqualsAndHashcode annotation 为你处理这件事。当然,您可能仍然应该阅读@studiousjoseph在答案中提到的链接,这样您就可以理解如何编写适当的equals/hashcode方法,但是这是一个可以帮助您自己编写这些方法的一些痛苦和陷阱的工具。

    正如其他人所提到的,在您的情况下,您至少需要在您的关系类上使用该注释或重写equals()/hashcode(),如果您需要对它们进行自定义的equals行为,也可能需要在您的角色和roletype类上使用该注释或重写equals()/hashcode()。

    编辑:我刚注意到你在使用Netbeans。如果您想尝试Lombok,这可能是相关的: http://wiki.netbeans.org/Lombok#IDE_support

        4
  •  -1
  •   Brian S    14 年前

    正如其他人所说,您需要实现 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; :这基本上是因为 等于 方法,不生成(或需要 try / catch 为了) ClassCastException .