references :
Have your objects provide the standard set of services (methods), that Object provides.
Example - the Name class you just wrote :
Name name = new Name ("John", "Doe"),
sameName = new Name ("John", "Doe");
If you decide that name and sameName both represent a single 'thing', the following tests should pass :
assertEquals ( "/1-1", name , sameName );
assertEquals ( "/1-2", name.hashCode() , sameName.hashCode() );
assertEquals ( "/1-3", name.toString() , sameName.toString() );
Problem : by default, they all fail.
=> you must override
equals(),
hashCode(), and
toString().
public boolean equals (Object o)
{
if (this == o) return true ;
if (! (o instanceof Name )) return false ;
final Name obj = (Name) o;
return
obj.__firstName .equals( this.__firstName )
&& obj.__lastName .equals( this.__lastName )
;
}
(code generated by the CanonicizerDoclet)
The stupid way
(not recommended; but it works !) :
public int hashCode () {
return 1 ;
}
The smart way
public int hashCode ()
{
int result = 17;
result = 37 * result + __firstName.hashCode() ;
result = 37 * result + __lastName.hashCode() ;
return result ;
}
(code generated by the CanonicizerDoclet)
(recipe from Effective Java)
| If you override equals(), but not hashCode(), you can get some nasty surprises : |
Set s = new HashSet();
s.add(name);
s.add(sameName);
assertEquals ( "FATAL ERROR : object added twice to the set" , 1 , s.size() ); <-- fail !
Java collections use equals() and hashCode() to store/retrieve objects => they must be consistent.
toString() is used mostly for debugging => write it for human eyes.
public String toString () {
return "[Name: " + __firstName + "," + __lastName + "]" ;
}
name.toString() => "[Name: John, Smith]"
--AlainRavet