从arraylist中删除重复项

时间:2011-06-15 18:05:18

标签: java arraylist

我正在尝试从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);
                    }
                }
            }
    }
    }

但是,似乎没有处理列表中的最后一个对象。也许有人可以查明错误

9 个答案:

答案 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插入适合类型安全的代码中。