1

First of all, I would like to say that I have searched for an answer to this, but did not get an suitable solution. So I have decided to post it here.

I have an ArrayList of Objects (ArrayList(Provider)). The Provider Object has First Name, Last Name, NPI Number, List (I have not listed all the fields).

Provider {

        private long providerId;
        private String npiNumber;
        private PersonName providerName;
        private List<Address> providerAddresses;

        }

Now I want to find if the ArrayList has duplicates based on these attributes (First Name, Last Name, NPI, Addresses). Each Provider will have 2 addresses. The issue we have is the Provider Object is generated from XSD and cannot be modified. So I cannot override the equals and hashcode methods. So The Hashset(list) does not work.

So what is the best way to check if the ArrayList has duplicate objects. Please let me know

Thanks

Harish

Harry
  • 546
  • 6
  • 22
  • 50

4 Answers4

3

You can create a TreeSet<Provider> with a custom Comparator<Provider> Or a TreeMap if you want to know what the duplicates are.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

You can use the HashSet(list) trick by wrapping your addresses.

class AddressWrapper {
    Address address;
    public boolean equals(Object o) {
        if(!(o instanceof AddressWrapper)) return false;
        AddressWrapper aw = (AddressWrapper)o;
        Address a = aw.address;
        return a.street.equals(address.street)
            && a.otherValues.equals(address.otherValues); // fill these in

    }
    public int hashCode() {
        int hash = address.street.hashCode();
        hash = hash * 31 + address.otherValues;
        // others
        return hash;

    }

}
corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • Thank you glowcoder. I have created a ProviderWrapper and able to override the equals method & it works for Strings & int fields in the Provider Object. But the issue is the Provider has a field: List
    . I have created an AddressWrapper for the Address Object, but how do I use the AddressWrapper instead of Address object under Provider. Hope you understand my question
    – Harry Mar 31 '11 at 19:01
  • In your `ProviderWrapper.equals()` method, you can create an `List` from your `List
    `
    – corsiKa Mar 31 '11 at 19:42
1

Have you tried apache commons CompareToBuilder? It uses reflection to compare objects and can even handle private members. I believe it can do a deep compare, as well so it should be able follow your List elements and compare them. However if it can't you might have to compare them seperatley.

Anyways you should be able to use some combination of TreeSet and a custom comparator. Note this code is untested and might not be the most performant way but it should get the job done with minimal code.

        class DupeComparator implements Comparator{

            @Override
            public int compare(Object o1, Object o2){

                // Might have to roll your own compare here if CompareToBuilder doesn't do
                // a deep compare of your List<Address> Fields
                return CompareToBuilder.reflectionCompare(o1, o2);
            }           
        }

        TreeSet set = new TreeSet(new DupeComparator());

        // this should give you a tree set without duplicates
        set.addAll(providerList); 

        // If you need to know which elements are dupilicates you'd
        // probably have to iterate your list           
        for(Provider p : providerList){
            if(!set.contains(p))
                set.add(p);
            else
                System.out.printn(p + " is a duplicate");
        }


EDIT: Changed from EqualsBuilder to CompareToBuilder which makes more sense in this case.
Jberg
  • 925
  • 7
  • 12
0

Here a link how to tweak the equals and hashCode method with JAXB:

http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins

Puce
  • 37,247
  • 13
  • 80
  • 152