Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arraylist looping malfunction

I have a MainList that has 61 elements and a subList of 9 elements. Out of the 9 elements in subList, 8 of them is in MainList.

My objective is simply remove those objects that existed in both list.

for(int i = 0; i < subList.size();i++){
    for(int j = 0; j < mainList.size();j++){
        if(subList.get(i).equals(mainList.get(j))){
            mainList.remove(j);
            subList.remove(i);

            break;
        }
    }
} 

The problem I'm facing is, after the forloop, subList still remains 5 elements, meaning the forloop only able to find 4 objects similar.

Afterwards, I wrote another forloop to debug the situation as below:

for(int i = 0; i < subList.size();i++){
    for(int j = 0; j < mainList.size();j++){
    if(subList.get(i).equals(mainList.get(j))){
            System.out.println("something");
        }
   }
}

And I get to see 4 times of "something". I'm wondering why the first forloop doesnt find all similar objects?

like image 911
SuicideSheep Avatar asked Mar 13 '26 02:03

SuicideSheep


2 Answers

Why not use the Collection.removeAll() method:

mainList.removeAll( subList );

remove()'ing from a Listchanges the indices. It is recommended to use an Iterator to traverse and remove from collections:

for ( Iterator<...> iterator = mainList.iterator() ; iterator.hasNext() ; ) {
    Object o = iterator.next();
    if (subList.contains( o )  ) { iterator.remove(); }
}

Cheers,

like image 61
Anders R. Bystrup Avatar answered Mar 14 '26 18:03

Anders R. Bystrup


When you remove an element from an ArrayList, the indices of the elements following it are decreased by one, so you should decrement the indices of your loop to account for that.

For example, subList.remove(3); will move the element prviously at the index 4 to index 3, so in order for your loop not to skip that element, you should decrement the index of your loop.

for(int i = 0; i < subList.size();i++){
    for(int j = 0; j < mainList.size();j++){
        if(subList.get(i).equals(mainList.get(j))){
            mainList.remove(j);
            subList.remove(i);
            i--;
            j--; // actually j-- may not be needed, since you break
                 // from the inner loop and start a new inner loop
            break;
        }
    }
} 
like image 42
Eran Avatar answered Mar 14 '26 18:03

Eran



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!