-1

I am overriding equals and hashcode method to define uniqueness of an object but it does not seem to work. Below is the code to override equals and hashcode but it is not working. What are some other methods to remove duplicates?

public class Test {

    private static class Model {

        private String firstName;
        private String lastName;

        public Model(final String firstName, final String lastName){
            this.firstName = firstName.trim();
            this.lastName = lastName.trim();
        }


        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

        @Override
        public String toString() {
            return MoreObjects.toStringHelper(this).add("firstName", firstName).add("lastName", lastName).toString();
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Model model = (Model) o;
            return firstName.equalsIgnoreCase(model.firstName) &&
                    lastName.equalsIgnoreCase(model.lastName);
        }

        @Override
        public int hashCode() {
            return Objects.hash(firstName, lastName);
        }
    }

    public static void main(String[] args){

        final List<Model> listWithDuplicates = new ArrayList<>();
        listWithDuplicates.add(new Model("a","b"));
        listWithDuplicates.add(new Model("A","b"));
        listWithDuplicates.add(new Model("a","B "));
        listWithDuplicates.add(new Model("A","B"));

        System.out.println(new HashSet<Model>(listWithDuplicates));

    }
}

Expected: [Model{firstName=a, lastName=b} Actual: [Model{firstName=a, lastName=b}, Model{firstName=A, lastName=b}, Model{firstName=a, lastName=B}, Model{firstName=A, lastName=B}]

pdojo
  • 3
  • 2
  • What do you mean by *it does not seem to work*? – Andronicus Apr 25 '19 at 06:03
  • 4
    Your `equals` does not agree with your `hashCode`. Your `equals` is case insensitive and your `hashCode` is not. As you have it, two objects that are supposed to be equal might have different hashcodes. – khelwood Apr 25 '19 at 06:04
  • If you are using eclipse, you can generate `hashCode` and `equals` – deHaar Apr 25 '19 at 06:07

1 Answers1

0

You have tested equality with equalsIgnoreCase and not with equals:

return firstName.equalsIgnoreCase(model.firstName) &&
       lastName.equalsIgnoreCase(model.lastName);

while in the hashCode the firstName and lastNameis hashed considering the exact case that is used to represent the string.

To make it case-insensitive adjust your hasdCode to be either all lowercase or uppercase:

@Override
public int hashCode() {
       firstName = firstName != null ? firstName.toLowerCase() : firstName;
       lastName = lastName != null ? lastName.toLowerCase() : lastName;
       return Objects.hash(firstName, lastName);
}
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44