Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating over a list, modifying each element: is there a faster method?

Tags:

java

list

I have an List of Strings and I would like to trim() each element of the list.

Currently, I'm using an ArrayList, doing a simple loop through the elements, and adding the trimmed element to a return list, like so:

int listLen = listToTrim.size();

List<String> trimmedList = new ArrayList<String>( listLen );

for ( int i = 0; i < listLen; i++ ) {
    trimmedList.add( listToTrim.get( i ).trim() );
}

return trimmedList;

For large lists, would there be a more efficient way of doing this?

like image 690
evanjdooner Avatar asked Sep 09 '13 10:09

evanjdooner


People also ask

Can you modify list while iterating?

The general rule of thumb is that you don't modify a collection/array/list while iterating over it. Use a secondary list to store the items you want to act upon and execute that logic in a loop after your initial loop.

How do you modify an ArrayList while iterating?

Replace element in arraylist while iterating Do not use iterator if you plan to modify the arraylist during iteration. Use standard for loop, and keep track of index position to check the current element. Then use this index to set the new element. Java program to search and replace an element in an ArrayList.

Which type of loop is most effective to iterate over a list?

Using an iterator, or using a foreach loop (which internally uses an iterator), guarantees that the most appropriate way of iterating is used, because the iterator knows about how the list is implemented and how best go from one element to the next.


2 Answers

Nope, you're good. That's about as efficient as it'll get. There's no magic that avoids iterating.

One point to keep in mind, 'though: If listToTrim is not a random-access-list (i.e. it does not implement RandomAccess), then using an Iterator (or an enhanced for-loop, which uses an Iterator internally) instead of a traditional for-loop is usually much more efficient. The most notable List that doesn't implement RandomAccess is the LinkedList. Calling l.get(300) on a LinkedList with 600 elements will have to iterate through ~300 elements to get the correct one!

Modifying your code to use an enhanced for-loop would look like this:

public List<String> trimStrings(Listy<String> listToTrim) {
    List<String> trimmedList = new ArrayList<String>(listToTrim.size());
    for (String str : listToTrim) {
      trimmedList.add(str.trim());
    }
    return trimmedList;
}

If you don't need the original list any more, then re-using the original list can save memory and improve performance:

public void trimStringsInPlace(List<String> listToTrim) {
    ListIterator<String> it = listToTrim.listIterator();
    while (it.hasNext()) {
      it.set(it.next().trim());
    }
}
like image 126
Joachim Sauer Avatar answered Oct 18 '22 23:10

Joachim Sauer


Not really; you have to call trim on each element, and preallocating an ArrayList of the right size is as fast as you can get. Java 8 will allow you to make the syntax more compact, but iterating and trimming is the minimum amount of work here.

like image 29
chrylis -cautiouslyoptimistic- Avatar answered Oct 18 '22 21:10

chrylis -cautiouslyoptimistic-