Complete hashcode, toString, and equals