File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Filtering out some elements from a ArrayList Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Filtering out some elements from a ArrayList" Watch "Filtering out some elements from a ArrayList" New topic
Author

Filtering out some elements from a ArrayList

olze oli
Ranch Hand

Joined: Jun 20, 2009
Posts: 148
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

Joined: Oct 27, 2005
Posts: 19651
    
  18

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:


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
olze oli
Ranch Hand

Joined: Jun 20, 2009
Posts: 148
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

Joined: Oct 27, 2005
Posts: 19651
    
  18

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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Filtering out some elements from a ArrayList
 
Similar Threads
Collection
K&B Book for Scjp 6 - Chapter 5 question 8 doubt
using i=i++
HashSet problem
Best possible solution for problem below