Найти дубликаты объектов в архиве Java - PullRequest
1 голос
/ 31 марта 2011

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

У меня есть ArrayList объектов (ArrayList (Provider)). Объект провайдера имеет имя, фамилию, номер NPI, список (я не перечислил все поля).

Provider {

        private long providerId;
        private String npiNumber;
        private PersonName providerName;
        private List<Address> providerAddresses;

        }

Теперь я хочу выяснить, есть ли в ArrayList дубликаты на основе этих атрибутов (Имя, Фамилия, NPI, Адреса). Каждый провайдер будет иметь 2 адреса. Проблема, с которой мы сталкиваемся, заключается в том, что объект поставщика генерируется из XSD и не может быть изменен. Поэтому я не могу переопределить методы equals и hashcode. Поэтому Hashset (список) не работает.

Итак, как лучше всего проверить, есть ли в ArrayList дублированные объекты. Пожалуйста, дайте мне знать

Спасибо

Хариш

Ответы [ 4 ]

3 голосов
/ 31 марта 2011

Вы можете создать TreeSet<Provider> с пользовательским Comparator<Provider> или TreeMap, если хотите знать, что такое дубликаты.

1 голос
/ 31 марта 2011

Вы пробовали Apache Commons CompareToBuilder?Он использует отражение для сравнения объектов и может даже обрабатывать закрытые члены.Я считаю, что это может сделать глубокое сравнение, так что он должен иметь возможность следить за вашими элементами списка и сравнивать их.Однако, если это невозможно, вам, возможно, придется сравнить их по отдельности.

В любом случае вы сможете использовать некоторую комбинацию 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.
1 голос
/ 31 марта 2011

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

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;

    }

}
0 голосов
/ 31 марта 2011

Вот ссылка, как настроить метод equals и hashCode с помощью JAXB:

http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins

...