Find Duplicate Objects in an java arraylist
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,开发者_Go百科 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
You can create a TreeSet<Provider>
with a custom Comparator<Provider>
Or a TreeMap if you want to know what the duplicates are.
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;
}
}
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.
Here a link how to tweak the equals and hashCode method with JAXB:
http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins
精彩评论