Basic To Advance Ways To Iterate Over A List In Java | CodersTea
Home Java Basic to Advance ways to iterate over a List in Java

Basic to Advance ways to iterate over a List in Java

by Imran Shaikh
Published: Last Updated on 936 views
Basic to Advance ways to iterate over a List in Java

Hey, Tea Lovers! Collection Framework is a very powerful library in Java. Every update in Java adds some more and interesting features to this. Today, we will go over how you can iterate over a List, be it ArrayList, LinkedList, or any other. We will take a look at them in ascending order from the basic loop to iteration to Stream API. And also, figure out which one is best suitable for our requirements. So, make your tea and get ready to sip and code.

You can follow me on social media via @coderstea on TwitterLinkedinFacebook, or Instagram. We also share high-quality videos about programming on our Youtube channel. You can also publish your post on CodersTea, just share your thought on Contact Us or let us know in the comments.

Basic Looping over List

  • for-loop
  • enhanced for-loop
  • while-loop

By basic, I meant using the primitive loops, such as for-loop. In this, you loop with the index. You can use a while-loop similar to a for-loop. And the other one is enhanced for-loop. No need of maintaining the index, you directly get the item in a defined variable. But I would suggest not to modify the list when using enhanced for-loop. Have a look at the code.

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 6, 7, 8, 10);
// basic for loop
for (int i = 0; i < list.size(); i++) {
    int data = list.get(i);
    System.out.println("Data at index " + i + " is " + data);
// enhanced for-loop
for (Integer data : list) {
    System.out.println("Data is "+ data +" and it is already given to you in variable");
// while-loop
int i = 0;
while(i < list.size()){
    int data = list.get(i);
    System.out.println("Data at index " + i + " is " + data);

Advanced Iteration of List via iterator(s)

  • Iterator
  • ListIterator
  • For-each

Collection Framework comes with its way of doing things. You can iterate over the list with the help of the Iterator. It gives you the Object of Iterator<E> and you can traverse through it via next().

// Iterator
Iterator<Integer> iterator = list.iterator();
    System.out.println("Data is " +;

ListIterator<E> is kind of similar to the Iterator but has a lot more functionality. You can move backward as well and modify the current element as well.

// ListIterator
ListIterator<Integer> listIterator = list.listIterator();
    System.out.println("Data is " +;
    listIterator.set( * 100);
System.out.println("After modifying via ListIterator ...");
    System.out.println("Data is " +;

In both cases, you can modify the list along the way. This may not be a good idea, since we should focus on immutability to have a maintainable code to reduce errors and debugging time in the future. And it is recommended to use enhanced for-loop instead of this.

You can also use the forEach on the list directly. You have to pass the Consumer<E> for the parameter. You can learn more about the Consumer here. The Functional Interface gives you the power of lambda. WIth method reference, it becomes much more cleaner.

// forEach
list.forEach(e -> System.out.println("Data is " + e));
// you can use the method reference to print the value only
System.out.println("With method reference on for-each");

The Pro-Level List Iteration: Stream API

Before starting on stream API, I would like you to get familiar with the Stream API. I have written a post on this explaining the very basics of the Stream API on Stream API: The Hero Without a Cape.

Ok, back to the list. As you know, Stream allows you to iterate over the List or other Collection. But, unlike other iteration methods we have seen, we have intermediate and terminal functions to perform actions. A stream doesn’t start until a terminal operation is called, so it is a passive one.

The stream is a much more refined and declarative way to perform actions on the list. It doesn’t modify the original list. Intermediate functions do action on the element of the list in the pipeline. And again, with the help of lambda, it is so much powerful. I use the stream all the time. I don’t have to keep track of many things, instead just reading the functions tells me what is happening. For example, if I see a filter then we are checking for some conditions, the map is when we are using the element and converting it to another object and so on.

To be honest, it’s so customizable, I couldn’t figure out which one to show you guys. So I kept it simple and wrote comments to tell what’s happening in the code.

// stream api
// for each with stream;
// using intermediate function in between
Optional<Integer> sum =
        .filter(e -> e % 2 == 0) // only even number
        .map(e -> e * 2) // multiplying each even number by 2
        .reduce((e, acc) -> e + acc);// summing up all the data
System.out.println("Sum of even number is "+ sum.get());

We are getting an Optional, meaning there may or may not be a value present and reduce the chances of NullPointerException. You can learn more about it on Reduce NullPointerExceptions with Optional in Java 8 & Beyond.


So these were the options you have for iterating over the list. I use Stream API way more often because I don’t need to maintain the multiple variables to keep track of what’s happening inside the loop. In the case of simple operation, enhanced for loop might be a good option or forEach. But restrain yourself from using Iterators, they are things of the past and not very optimal.

You can find all the code described here at GitHub. You can also all other code from coder’s tea at GitHub, GitLab, BitBucket.

See you in the next post. Till then, sip and code.

Notify of
Inline Feedbacks
View all comments

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More