удаление дубликатов из массива - PullRequest
0 голосов
/ 15 июня 2011

Я пытаюсь удалить дубликаты объектов из массива, см. Код ниже:

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 ]

4 голосов
/ 15 июня 2011

Попробуйте добавить j--; после удаления элемента.Это переиндексирует вас и решит вашу проблему.

3 голосов
/ 15 июня 2011

Основной недостаток в том, что поскольку ListArray является изменяемым, после удаления одного элемента ваши индексы должны быть перенастроены.

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 голосов
/ 15 июня 2011
    public static void removeDuplicates(ArrayList list) {
            HashSet set = new HashSet(list);
            list.clear();
            list.addAll(set);
    }

переопределить равно и присвоить хэш-код

1 голос
/ 23 августа 2011

Код ниже работал для меня. Попробуйте. Вы можете манипулировать методом сравнения на свой вкус ArrayList customers = .....;<br> Set customerlist = new TreeSet(new Comparator(){</p> <pre><code> @Override public int compare(Customer c1, Customer c2) { return c1.getSocialSecurityNo().compareTo(c2.getSocialSecurityNo()); } }); customerlist.addAll(customers); customers.clear(); customers.addAll(customerlist);

1 голос
/ 15 июня 2011

custormers = новый ArrayList (новый HashSet (клиенты))

гарантирует, что равные и хеш-метод правильно реализованы

0 голосов
/ 15 июня 2011

Моей первой мыслью было использование наборов, как уже упоминали другие. Другой подход заключается в использовании версии foreach для Java вместо использования индексов. Общий подход:

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 в код, где это необходимо для безопасности типов.

0 голосов
/ 15 июня 2011

Итак, о том, как сделать это правильно:

Ваши объекты Customer должны иметь метод equals () и hashCode () , который выполняет сравнение. (Или у вас просто будет только один объект Customer для каждого клиента, что будет означать, что ваша модель данных должна быть скорректирована. Тогда подойдет hashCode / equals по умолчанию.)

Если у вас есть это, вы можете заменить свои три вложенных if одним:

    if(customers.get(i).equals(customers.get(j)) {
       customers.remove(j);
    }

Это еще не решило бы вашу проблему, но упростило бы более четкое ее рассмотрение. Если вы посмотрите, какие объекты сравниваются с какими другими, вы увидите, что после каждого удаления объекта из списка, следующий имеет тот же индекс, что и тот, который вы только что удалили, и вы не будете сравнивать текущий объект с ним. Как сказано, j-- после удаления решит это.

Более производительным решением было бы использование набора (который гарантированно не содержит дубликатов). В вашем случае, 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);

Если вам действительно не нужен список (то есть индексированный доступ), пропустите последнюю строку и просто используйте вместо этого набор.

0 голосов
/ 15 июня 2011

Прежде чем добавить их в список в вышеприведенном цикле, почему бы вам не проверить

if(!cutomers.contains(accounts.get(i).getCustomer())
{
//add them if it doesn't contain
}

Это должно спасти вас от выполнения второго цикла

Редактировать: необходимо переопределитьметод равен .

0 голосов
/ 15 июня 2011

Это ваша int j=i+1, которая вызывает проблемы. Вам нужно проверять последнее значение в списке клиентов для каждой итерации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...