1

How do I fetch unique list of object arrays in below code:

    import java.util.*;

    class t1 {
        public static void main(String[] args) {

            Object[] o1 = new Object[] { null, "[email protected]", "ENG", "775778435", 1};
            Object[] o2 = new Object[] { null, "[email protected]", "ENG", "775778435", 1};

            List<Object[]> result = new ArrayList<Object[]>(); 
            result.add(o1); 
            result.add(o2); 

            // The above result list is coming from some DB & I cannot change the structure of above script. 
            // Now, I need to remove the duplicates from this result list meaning I need to find duplicates from the objects within the list.
            // I tried below code but it still prints duplicates. Any help???

            Set<User> setResult = new HashSet<User>();
            User userInfo = null;

            for (Object[] userData : result) {
                userInfo = new User((String)userData[0], (String)userData[1], (String)userData[2], (String)userData[3], (Integer) userData[4]);
                setResult.add(userInfo);
            }

            Iterator it = setResult.iterator();
            while (it.hasNext()) {
                Object o = it.next();

                User u = (User) o;
                System.out.println("non-duplicate = " + u.getEmail());
            }

            // Expected result: non-duplicate = [email protected]
            // Actual   result: non-duplicate = [email protected] getting printed twice i.e. duplicate not getting removed!
        }
    }

    class User {
        public String firstName;
        public String email;
        public String language;
        public String productCode;
        public int status;

        public User() {         
        }

        public User(String fName, String userId, String lang, String productCode, int status) {
            this.firstName = fName;
            this.email = userId;
            this.language = lang;
            this.productCode = productCode;
            this.status = status;
        }   

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getLanguage() {
            return language;
        }

        public void setLanguage(String language) {
            this.language = language;
        }

        public String getProductCode() {
            return productCode;
        }

        public void setProductCode(String productCode) {
            this.productCode = productCode;
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

        @Override
        public int hashCode() {
            int fNameHash = 0;
            int lNameHash = 0;
            int emailHash = 0;
            int langHash = 0;
            int productCodeHash = 0;

            if (this.firstName != null) {
                fNameHash = this.firstName.hashCode();
            }

            if (this.email != null) {
                emailHash = this.email.hashCode();
            }

            if (this.language != null) {
                langHash = this.language.hashCode();
            }

            if (this.productCode != null) {
                productCodeHash = this.productCode.hashCode();
            }

            return (fNameHash + lNameHash + emailHash + langHash + productCodeHash + this.status);
        }

        @Override
        public boolean equals(Object obj) {
            if(obj != null && obj instanceof User) {
                User temp = (User) obj;

                if (this.firstName != null && temp.firstName != null && this.firstName.equalsIgnoreCase(temp.firstName) 
                   && this.email != null && temp.email != null && this.email.equalsIgnoreCase(temp.email) 
                   && this.language != null && temp.language != null && this.language.equalsIgnoreCase(temp.language)
                   && this.productCode != null && temp.productCode != null && this.productCode.equalsIgnoreCase(temp.productCode)
                   && this.status == temp.status) {             
                    return true;
                }
            }
            return false;
        }   
    }

My expected result is to print [email protected] only once but its getting printed twice!!

Can any one tell me how to correct this code?

Thanks!

3 Answers 3

2

The problem is that your User.equals will predictably return false because both instances have null firstNames:

if (this.firstName != null && temp.firstName != null && this.firstName.equalsIgnoreCase(temp.firstName) 

As a result, even though they have identical hashCode, it's merely treated as a collision rather than a match, since equals is broken.

Try correcting that :-) Replacing the logic with something like...

firstName == temp.firstName || firstName != null && firstName.equalsIgnoreCase(temp.firstName)

... should work ;-)

You can see a fully-working version here.


As an aside, you forgot to ever assign lNameHash in User.hashCode.

Sign up to request clarification or add additional context in comments.

1 Comment

Can you please help me in correcting it? Can you please provide me the sample code? If I remove null check for fName in equals method, it gives null pointer exception....How do I do it then?
1

Both your equals method and your hashcode method are implemented incorrectly.

  • Your equals method returns false when both objects have null members.
  • Your implementation of hashCode can return different hash codes for some objects which compare equal.

You must provide correct implementations of equals and hashCode to be able to use your objects in a HashSet.

2 Comments

...Can you please help me in correcting it...If I remove null check for fName in equals method, it gives null pointer exception....How do I do it then?
@Mike: What IDE do you use? Almost all decent IDEs can give you a working implementation of equals and hashCode. Generate them, then adjust them if necessary (e.g. adding the case insensitivity). Remember that every change you make to equals must be reflected in hashCode too.
0

The problem is with the firstName value that is null for both objects. Because of this the equals() method return false and both your objects are considered distinct by the Set.

Try changing your equals and hashcode with the following:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof User)) return false;

    User user = (User) o;

    if (status != user.status) return false;
    if (email != null ? !email.equals(user.email) : user.email != null) return false;
    if (firstName != null ? !firstName.equals(user.firstName) : user.firstName != null) return false;
    if (language != null ? !language.equals(user.language) : user.language != null) return false;
    if (productCode != null ? !productCode.equals(user.productCode) : user.productCode != null) return false;

    return true;
}

@Override
public int hashCode() {
    int result = firstName != null ? firstName.hashCode() : 0;
    result = 31 * result + (email != null ? email.hashCode() : 0);
    result = 31 * result + (language != null ? language.hashCode() : 0);
    result = 31 * result + (productCode != null ? productCode.hashCode() : 0);
    result = 31 * result + status;
    return result;
}

Best way is to have equals and hashcode generated from your IDE as suggested in another answer.

2 Comments

Name can be null & that's the requirement. How do I fix it?
If I remove null check for fName in equals method, it gives null pointer exception....How do I do it then?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.