» Home » Java » 7 Best Ways You can Loop through Lists in Java

7 Best Ways You can Loop through Lists in Java

by Imran Shaikh
Published: Last Updated on 1983 views
7 Best Ways You can Loop through Lists in Java

Hey, Tea Lovers! Let’s look at the 7 ways you can iterate or loop through a Java List. These are ordered from basic to advance to pro level. So let’s jump to see different types of loops in java

I will use the same list throughout all the code samples.

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 6, 7, 8, 10);

Basic Level of Loops

First, let’s look at the basic level of looping. These are your for-loop, while-loop, and enhanced for-loop. Let’s take a look at them one by one.

for-loop in Java

in For Loop, you integrate list sing index. The sample code is as follows.

for (int i = 0; i < list.size(); i++) {
    int data = list.get(i);
    System.out.println("Data at index " + i + " is " + data);


In While Loop, it loops while or until a given condition is true. For example, while we reach the end of the List, keep iterating.

int i = 0;
while(i < list.size()){
    int data = list.get(i);
    System.out.println("Data at index " + i + " is " + data);

Be careful of while-loop though, if not tested properly, you may have to give 10 folds of AWS bill 😱.

Enhanced for-loop

Unlike, for-loop or while-loop, In 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 within the loop when using enhanced for-loop. Have a look at the code.

for (Integer data : list) {
    System.out.println("Data is "+ data +" and it is already given to you in variable");

Advance Loops in Java (Iterators)

The followings are the advanced level loop. Well, not exactly the loops, but Iterators. They simply iterate over the List.

  • Iterator
  • ListIterator
  • For-each

Iterator Class in Java

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 " + iterator.next());

ListIterator In Java

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.next());
    listIterator.set( listIterator.next() * 100);
System.out.println("After modifying via ListIterator ...");
    System.out.println("Data is " + listIterator.next());

Drawback of Iterator and ListIterator

In both cases, Iterator and ListIterator, 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.

ForEach in List and Collections

You can 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. This 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 Loop

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 = list.stream()
        .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 lopping through or 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. HAKUNA MATATA!!!

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

Would love your thoughts, please comment.x