Iterate through a list, change each item: is there a faster method?

I have a List of String , and I would like to trim() each element of the list.

I am currently using ArrayList , doing a simple loop through the elements and adding the clipped element to the returned list, for example:

 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 larger lists, would there be a more efficient way to do this?

+6
source share
5 answers

No, you're good. It is as effective as it gets. There is no magic that avoids iteration.

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

Changing the code to use the extended for loop will 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 no longer need the original list, reusing 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()); } } 
+14
source

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

+3
source

In addition, instead of creating a new ArrayList, you can use ArrayList # set () . This can significantly reduce memory for large lists.

 for ( int i = 0; i < listLen; i++ ) { listToTrim.set(i,listToTrim.get( i ).trim()); } 
+3
source

Joachim already answered the question. But one sentence -

listToTrim - when you add items to listToTrim, crop first before adding. Thus, you do not need to repeat and modify or create another list just for this. This does not sound logical.

Edit based on comment:

 String fruits = "Apple, Banana , Mango, Passion Fruit, Grapes "; List<String> fruitList = Arrays.asList((fruits.trim()).split("\\s*,\\s*")); // Trim first and then regex matches spaces before and after comma for(String fruit : fruitList){ System.out.println("Fruit: " + fruit + "\tLength: " + fruit.length()); } 

Output:

 Fruit: Apple Length: 5 Fruit: Banana Length: 6 Fruit: Mango Length: 5 Fruit: Passion Fruit Length: 13 Fruit: Grapes Length: 6 
+3
source

Joachim understood this correctly. People who say that you need to trim your lines before putting them on the first list also understood correctly.

In any case, if the latter is not an option for you, there may be an alternative approach: are you sure you will use all the trimmed lines? Or will you use only some of them, let's say, perhaps only the first five of them? Then it could be a bust to crop them all.

You can create a special implementation of List that will retain the original list, but will produce items trimmed. Here is what I mean:

 public class ImmutableStringTrimmingList extends AbstractList<String> { private final List<String> stringList; public ImmutableStringTrimmingList(List<String> stringList) { this.stringList = stringList; } @Override public String get(int index) { return stringList.get(index).trim(); } @Override public int size() { return stringList.size(); } } 

ImmutableStringTrimmingList stores the original list (therefore, any changes to this list will also be distributed here) and hand out String objects that are lazily trimmed. This can be useful if you do not want to do any unnecessary work, as it will only trim the lines requested by get() . It can also be adapted to cache the cropped object, so it does not have to retrieve it every time. But this is a practice for you if you find this class useful.


Or, if you are a Guava user, you can use Lists.transform() , which basically does the same, is also lazy.

 List<String> trimmedList = Lists.transform(list, new Function<String, String>() { @Override public String apply(String input) { return input.trim(); } }); 
+3
source

Source: https://habr.com/ru/post/953470/


All Articles