Reputation: 2454
I am trying to remove duplicate objects from an arraylist see code below:
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);
}
}
}
}
}
However, it seems that the last object in the list is not being processed. Perhaps someone can pinpoint the error
Upvotes: 0
Views: 2975
Reputation: 11
The code below worked for me. Give it a try. You can manipulate the compare method to suit your taste
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);
Upvotes: 1
Reputation: 18570
My first thought was to use Sets, as others have mentioned. Another approach would be to use Java's version of the foreach, instead of using indexes. A general approach:
public static ArrayList removeDuplicates(ArrayList origList) {
ArrayList newList = new ArrayList();
for (Object m : origList) {
if (!newList.contains(m)) {
newList.add(m);
}
}
return newList;
}
In testing, I just used Strings; I'd recommend inserting Customer into the code where appropriate for type safety.
Upvotes: 0
Reputation: 74750
So, about doing this right:
Your Customer objects should have an equals() and hashCode() method, which do the comparison. (Or you simply would have only one Customer object for each customer, which would mean your data model would have to be adjusted. Then the default hashCode/equals would do.)
If you have this, you can replace your three nested ifs with one:
if(customers.get(i).equals(customers.get(j)) {
customers.remove(j);
}
This would not yet solve your problem, but make it easier to have a clearer look on it. If
you look at which objects are compared to which others, you will see that after each removal
of an object from the list, the next one has the same index as the one which you just removed,
and you will not compare the current object to it. As said, j--
after the removal will solve this.
A more performant solution would be using a Set (which is guaranteed not to contain duplicates).
In your case, a HashSet<Customer>
or LinkedHashSet<Customer>
(if you care about the order)
will do fine.
Then your whole code comes down to this:
Set<Customer> customerSet = new HashSet<Customer>();
for(Account acc : accounts){
customerSet.add(acc.getCustomer());
}
List<Customer> customers = new ArrayList<Customer>(customerSet);
If you don't really need a list (i.e. indexed access), ommit the last line and simply use the set instead.
Upvotes: 0
Reputation: 13728
The basic flaw is that since the ListArray is mutable, once you remove one element your indexes have to be readjusted.
if(customers.get(i).getFirstName().compareToIgnoreCase(customers.get(j).getFirstName())==0){
customers.remove(j--);
}
also try subtracting one from your i loop:
for(int i=0;i<customers.size()-1;i++){
for(int j=i+1;j<customers.size();j++){
Upvotes: 3
Reputation: 15353
public static void removeDuplicates(ArrayList list) {
HashSet set = new HashSet(list);
list.clear();
list.addAll(set);
}
override equals and hashcode appropriatley
Upvotes: 2
Reputation: 4989
Try adding j--;
after removing an item. That will reindex for you and solve your issue.
Upvotes: 4
Reputation: 7070
Before you add them to the list in the above loop, why don't you check
if(!cutomers.contains(accounts.get(i).getCustomer())
{
//add them if it doesn't contain
}
It should save you from doing the second loop
Edit: Need to override the equals method.
Upvotes: 0
Reputation: 3096
custormers = new ArrayList(new HashSet(customers))
ensure the equals and hashmethod are correctly implemented
Upvotes: 1
Reputation: 14053
It's your int j=i+1
that causes trouble. You need to test with the last value of the customers list for each iteration.
Upvotes: 0