java 在java数组列表中查找重复对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5503646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find Duplicate Objects in an java arraylist
提问by Harry
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).
我有一个对象的 ArrayList (ArrayList(Provider))。提供者对象具有名字、姓氏、NPI 编号、列表(我没有列出所有字段)。
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.
现在我想根据这些属性(名字、姓氏、NPI、地址)查找 ArrayList 是否有重复项。每个提供者将有 2 个地址。我们遇到的问题是提供者对象是从 XSD 生成的,无法修改。所以我不能覆盖 equals 和 hashcode 方法。所以 Hashset(list) 不起作用。
So what is the best way to check if the ArrayList has duplicate objects. Please let me know
那么检查 ArrayList 是否具有重复对象的最佳方法是什么。请告诉我
Thanks
谢谢
Harish
哈里什
回答by Peter Lawrey
You can create a TreeSet<Provider>
with a custom Comparator<Provider>
Or a TreeMap if you want to know what the duplicates are.
如果您想知道重复项是什么,您可以TreeSet<Provider>
使用自定义Comparator<Provider>
或 TreeMap创建一个。
回答by corsiKa
You can use the HashSet(list) trick by wrapping your addresses.
您可以通过包装地址来使用 HashSet(list) 技巧。
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;
}
}
回答by Jberg
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.
您是否尝试过 apache commons CompareToBuilder?它使用反射来比较对象,甚至可以处理私有成员。我相信它可以进行深入比较,因此它应该能够遵循您的 List 元素并进行比较。但是,如果不能,您可能需要单独比较它们。
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.
无论如何,您应该能够使用 TreeSet 和自定义比较器的某种组合。请注意,此代码未经测试,可能不是最高效的方式,但它应该以最少的代码完成工作。
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.
回答by Puce
Here a link how to tweak the equals and hashCode method with JAXB:
这是如何使用 JAXB 调整 equals 和 hashCode 方法的链接:
http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins
http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins