I have a class with some non primitive members.
class Relation {
String name;
Role roleFrom;
Role roleTo;
}
class Role {
RoleType roleType;
String details;
}
class Role开发者_JAVA技巧Type {
String typeName;
String details;
}
Two relations are equal, when
- the name are equal
- the role type (identified by unique typeName) are equal for the Role members (roleFrom and roleTo)
How to write equals
and hashCode
for class Relation
. When tried with Netbeans, it only displays 3 fields (name
, roleFrom
and roleTo
). Is it because, one should not access the primitive types in roleFrom and roleTo (roleType -> typeName). Or, please show an implementation.
thanks.
When implementing hashCode()
and equals()
with non-primitive types of fields, it is assumed that these types also implement hashCode()
and equals()
correctly. So go to the other classes and implement hashCode()
and equals()
there (again using the auto-generation features of your IDE).
You should be extremely careful when overriding your equals
method, the best thing to do, as noted by Joshua Bloch in "Effective Java" is not to override it at all unless it is absolutely necessary, with the default equals implementation inherited from java.lang.Object every objects is only equals to itself.
I recommend that you check the following links to learn how to appropriately implement both your equals
and hashCode
methods. The last link shows you how to implement those methods when you have non primitive types as well as considerations for when you're dealing with inheritance.
- http://java.sun.com/javase/6/docs/api/java/lang/Object.html#equals%28java.lang.Object%29
- http://java.sun.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29
- http://www.javaworld.com/javaworld/jw-06-2004/jw-0614-equals.html
One potential solution, assuming that you
- you must override equals for your implementations
- you want to be lazy
- you don't mind treating hashcode() and equals() methods as black boxes
- don't mind using an extra tool at compile time
is to try using Lombok's useful EqualsAndHashcode annotation to handle this for you. Granted, you should probably probably still read the links that @StudiousJoseph mentioned in his answer so you understand how to write proper equals/hashcode methods, but this a tool that can help relieve some of the pains and pitfalls of writing these methods yourself.
As others have mentioned, in your case, you'll need to at least use that annotation or override equals()/hashcode() on your Relations class and potentially on your Role and Roletype class too if you need custom equals behavior on them.
Edit: I just noticed you are using Netbeans. This may be relevant if you want to try Lombok: http://wiki.netbeans.org/Lombok#IDE_support
As others said, you need to implement equals
/hashCode
for the other two classes as well. Where's an example:
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);
}
}
With regard to if(!(o instanceof XYZWK)) return false;
: this is basically just fail-fast for the equals
method, without generating (or needing a try
/catch
for) a ClassCastException
.
精彩评论