refactored equals and hashcode