# Filtering out some elements from a ArrayList

olze oli
Ranch Hand
Posts: 149
Hi,

i have a blackSuffix List which includes some file extensions like "ico png jpg jpeg mov avi" etc.
I also have a ArrayList which has about 500 links and i want to filter out all elements that end with a blackSuffix

Works almost, but there are still some elements which arent filtered out and i have absolutly no idea how this could happen.
Moreover, if i copy/paste this code, the second run filters some more elements but a few are still left...
Does anyone have any idea whats going wrong here? This already took me hours to figure out but i just dont get it...

Thanks in advance for any help.

Rob Spoor
Sheriff
Posts: 20661
65
Let's simplify your example.
This code should remove all even values. So let's run through the application:
list == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
i == 0: value == 0 so remove value 0; list == [1, 2, 3, 4, 5, 6, 7, 8, 9]
i == 1: value == 2 (1 is skipped) so skip; list == [1, 2, 3, 4, 5, 6, 7, 8, 9]
...

As you see, it skips the element just after deleting one. That's because the counter is increased but the index of all elements after the removed element is decreased by one.

There are four tricks to solving this:
1) decrease the counter by 1 after removing an element from the list to counteract the invalid increasing.
2) move the increasing of the counter from the for-loop to the loop body, but only if you don't remove an element: for (int i = 0; i < list.size(); ) { ... i++; }
3) traverse the loop in backwards order: for (int i = list.size() - 1; i >= 0; i--).
4) use an Iterator.

The fourth option is definitely the best because the Iterator takes care of maintaining the proper index. So:
Applied to your code:

olze oli
Ranch Hand
Posts: 149
Thanks alot for your help... again

What really confuses me: there's a remove(Object o); method and i thought i call this, so the index should not matter, doesnt it?
Thats why i'm not using the index i because i thought the same as you just told me - but with iterator its working. thanks!

Rob Spoor
Sheriff
Posts: 20661
65
It doesn't matter which remove method of the list you call, it will change the index of all elements with a previously higher index. The indexes will always be sequential, and if you remove the object with index 4, then another object will fill that gap. That object previously had index 5 which is again filled, etc. The counter is still increased though so one element, the one that now holds the index of the removed object, is skipped.