What's the replacement For-Each loop for filtering?

Although there are many advantages for each loop, but the problem is that it doesn't work when you want Filter (Filtering means removing an item from the list) of the List, can you make any replacement, since even indexing is not a good option. ...

+2


source to share


4 answers


What do you mean by "filtering"? Removing some items from the list? If so, you can use an iterator :

for(Iterator<MyElement> it = list.iterator(); it.hasNext(); ) {
    MyElement element = it.next();
    if (some condition) {
      it.remove();
    }
}

      

Update (based on comments):

Let's look at an example to illustrate how an iterator works. Let's say we have a list containing "A" and "B":



AABBA

We want to remove all these pesky B

s. So, using the above loop, the code would work like this:

  • hasNext ()? Yes. following(). element

    indicates 1st A.
  • hasNext ()? Yes. following(). element

    points to the second A.
  • hasNext ()? Yes. following(). element

    points to 1st B. remove (). the iterator counter does NOT change, it still points to where B is (technically not entirely correct, but logical that it works). If you must call remove () again, you will get an exception (because the list item no longer exists).
  • hasNext ()? Yes. following(). element

    points to the second B. The rest is the same as # 3
  • hasNext ()? Yes. following(). element

    indicates the third A.
  • hasNext ()? No, everything is ready. The list now has 3 items.

Update # 2 : The remove()

operation is indeed required for the iterator, but only because it is optional in the underlying collection. Bottom line here - if your collection supports it (and all collections in the Java Collection Framework do), so would an iterator. If your collection doesn't support it, you're out of luck anyway.

+11


source


ChssPly76's answer is the correct approach here, but I'm intrigued with respect to your thinking: "Index traversal is not a good option." In many cases - the general case, in particular the one that has ArrayList

- it is extremely effective. (Actually, in the case of Arraylist, I find that repeated calls are get(i++)

slightly faster than using Iterator, although not close enough to sacrifice readability).



In general, if the object in question implements java.util.RandomAccess , then accessing successive elements through the index should be roughly the same using an Iterator. If this is not the case (for example, LinkedList

would be a good counterexample), then you are correct; but don't turn this option out of control.

0


source


I had success with

filter(java.util.Collection collection, Predicate predicate) 

      

CollectionUtils method on collections of collections.

http://commons.apache.org/collections/api-2.1.1/org/apache/commons/collections/CollectionUtils.html#filter(java.util.Collection,%20org.apache.commons.collections.Predicate)

0


source


If you, like me, don't like modifying the collection when iterating through the elements, or if the iterator simply doesn't provide an implementation for deletion, you can use a temporary collection to just collect the elements you want to delete.Yes, yes, it's less efficient by compared to modifying the iterator, but it's clearer for me to understand what's going on:

List<Object> data = getListFromSomewhere();
List<Object> filter = new ArrayList<Object>();

// create Filter
for (Object item: data) {
  if (throwAway(item)) {
    filter.add(item);
  }
}

// use Filter
for (Object item:filter) {
  data.remove(item);
}

filter.clear();
filter = null;

      

0


source







All Articles