correctly implements equals and hashCode methods