我正在尝试从arraylist中删除重复的对象 见下面的代码:
ArrayList<Customer> customers=new ArrayList<Customer>();
for(int i=0;i<accounts.size();i++){
customers.add(accounts.get(i).getCustomer());
}
for(int i=0;i<customers.size();i++){
for(int j=i+1;j<customers.size();j++){
if(customers.get(i).getSocialSecurityNo().compareTo(customers.get(j).getSocialSecurityNo())==0){
if(customers.get(i).getLastName().compareToIgnoreCase(customers.get(j).getLastName())==0){
if(customers.get(i).getFirstName().compareToIgnoreCase(customers.get(j).getFirstName())==0){
customers.remove(j);
}
}
}
}
}
但是,似乎没有处理列表中的最后一个对象。也许有人可以查明错误
答案 0 :(得分:4)
删除项目后尝试添加j--;
。这将为您重新索引并解决您的问题。
答案 1 :(得分:3)
基本缺陷是,由于列表数组是可变的,因此一旦删除了一个元素,就必须调整索引。
if(customers.get(i).getFirstName().compareToIgnoreCase(customers.get(j).getFirstName())==0){
customers.remove(j--);
}
也尝试从你的i循环中减去一个:
for(int i=0;i<customers.size()-1;i++){
for(int j=i+1;j<customers.size();j++){
答案 2 :(得分:2)
public static void removeDuplicates(ArrayList list) {
HashSet set = new HashSet(list);
list.clear();
list.addAll(set);
}
覆盖equals和hashcode appropriatley
答案 3 :(得分:1)
custormers = new ArrayList(new HashSet(customers))
确保正确实现equals和hash方法
答案 4 :(得分:1)
以下代码对我有用。试试看。您可以操纵比较方法以适合您的口味
ArrayList customers = .....;
Set customerlist = new TreeSet(new Comparator(){
@Override
public int compare(Customer c1, Customer c2) {
return c1.getSocialSecurityNo().compareTo(c2.getSocialSecurityNo());
}
});
customerlist.addAll(customers);
customers.clear();
customers.addAll(customerlist);
@Override
public int compare(Customer c1, Customer c2) {
return c1.getSocialSecurityNo().compareTo(c2.getSocialSecurityNo());
}
});
customerlist.addAll(customers);
customers.clear();
customers.addAll(customerlist);
答案 5 :(得分:0)
这是导致麻烦的int j=i+1
。您需要使用每次迭代的客户列表的最后一个值进行测试。
答案 6 :(得分:0)
在将它们添加到上述循环中的列表之前,为什么不检查
if(!cutomers.contains(accounts.get(i).getCustomer())
{
//add them if it doesn't contain
}
它应该可以避免你做第二次循环
修改:需要覆盖equals方法。
答案 7 :(得分:0)
所以,关于这样做:
您的客户对象应该使用equals()和hashCode()方法进行比较。 (或者你只是每个客户只有一个Customer对象,这意味着你的数据模型必须调整。然后默认的hashCode / equals会这样做。)
如果你有这个,你可以用一个替换你的三个嵌套ifs:
if(customers.get(i).equals(customers.get(j)) {
customers.remove(j);
}
这还不能解决您的问题,但可以更容易地看清楚它。如果
你看看哪些对象与其他对象进行了比较,你会在每次删除后看到它们
列表中的一个对象,下一个对象的索引与刚刚删除的对象相同,
并且你不会将当前对象与它进行比较。如上所述,移除后j--
将解决此问题。
更高效的解决方案是使用Set(保证不包含重复项)。
在您的情况下,HashSet<Customer>
或LinkedHashSet<Customer>
(如果您关心订单)
会好起来的。
然后你的整个代码归结为:
Set<Customer> customerSet = new HashSet<Customer>();
for(Account acc : accounts){
customerSet.add(acc.getCustomer());
}
List<Customer> customers = new ArrayList<Customer>(customerSet);
如果您确实不需要列表(即索引访问),请简单地省略最后一行 改为使用该集。
答案 8 :(得分:0)
我的第一个想法是使用套装,正如其他人提到的那样。另一种方法是使用Java的foreach版本,而不是使用索引。一般方法:
public static ArrayList removeDuplicates(ArrayList origList) {
ArrayList newList = new ArrayList();
for (Object m : origList) {
if (!newList.contains(m)) {
newList.add(m);
}
}
return newList;
}
在测试中,我只使用了Strings;我建议将Customer插入适合类型安全的代码中。