How To Use Enhanced For Loops In Java (aka 'foreach')

Maaike van Putten
Maaike van Putten
hero image

Loops are important for controlling the flow of execution in Java.

Without loops, we would have a lot of duplications, as well as some very weird constructions in our code.

You might know some of these loops already:

  • (The traditional) for loop
  • while loop
  • do while loop

Loops are the backbone of many operations, from processing data, controlling the user interface, or executing a set of statements repeatedly under specific conditions, such as a counter for the for loop, or a boolean expression for the (do) while loop.

A more simplified way

Always improving, Java 5 introduced the enhanced for loop as a part of its syntax enrichment.

The enhanced for loop, otherwise known as a foreach loop, offers a simplified way to iterate over collections and arrays.

enhanced for loops

Unlike the traditional for loop that relies on a counter to navigate through elements, the enhanced for loop abstracts the counter, providing direct access to each element.

This means that the foreach loop is not only syntactically sleeker but also reduces the chances of errors, such as from off-by-one mistakes leading to OutOfBoundExceptions, making the code more readable and maintainable.

In this article, we’ll take a deeper look into the enhanced for (foreach) loop in Java, how it works, some use cases, best practices, and more.

Sidenote: If you struggle to understand what I cover here, or simply want to learn more and dive into Java, then be sure to check out my complete Java programming course or watch the first few videos for free.

learn java

You’ll learn Java coding from scratch, solidify your knowledge with exercises, build fun projects, and gain the skills you need to get hired as a Java Developer in 2024!

No prior programming knowledge is required. Just a willingness and enthusiasm to learn Java.

With that out of the way, let’s get into this guide!

Understanding the enhanced foreach loop

The enhanced foreach loop is a way of iterating through elements in arrays and collections in Java.

It simplifies the traditional for loop syntax and eliminates the need for manual index management, making your code more readable and less prone to errors.

The syntax of the enhanced for loop is elegantly simple.

For example

Here’s the general form:

for (Type variableName : collectionName) {
    // Body of loop
}

So let’s break this down:

  • for: The loop starts with the for keyword, indicating the start of the loop block
  • parentheses: Inside the parentheses, we first declare a variable of the same type as the elements in the array or collection. This variable will temporarily hold each element as the loop iterates through the collection
  • Type: This is the type of the elements in the array or collection you are iterating over
  • Colon: The colon (:) symbol is used to separate the variable declaration from the collection being iterated.
  • variableName: Is a temporary variable that holds the current element from the array or collection on each iteration
  • collectionName: The array or collection you want to iterate through
  • // Body of loop: This is the code you want to execute for every element in the array. In this body, you can use variableName and that will be holding the value of the element you’re currently iterating over

A quick note on the temporary variable creation and scope

The temporary variable created in the enhanced for loop is particularly noteworthy.

  • This variable is created at the beginning of each iteration, and exists only within the scope of the loop, meaning it cannot be accessed outside the loop
  • Also, the value of this variable changes every iteration, and is assigned the value of the current element from the array or collection that the loop is looping over. The scope of this temporary variable is limited to the loop itself

Basic example of the enhanced for loop

To help you understand the forloop a little easier, let’s walk through some examples.

We’ll start with a very basic example where we’re going to iterate over the elements of a collection of integers.

Suppose we have an array of integers, and we want to print each value:

int[] numbers = {1, 2, 3, 4, 5};

for (int number : numbers) {
    System.out.println(number);
}

In this example:

  • int is the Type
  • number is the temporary variable
  • numbers is the collection (in this case, an array) being iterated over
  • Each iteration of the loop assigns number the next value in the numbers array and prints it until all elements are processed

Now that we have seen a very basic example, let’s spice things up a bit and have a look at some more real-life cases.

Practical use cases for the foreach loop

The enhanced for loop finds its strength in simplifying data processing tasks.

Let's explore this with two practical use cases in the context of an Inventory Management System.

Use Case 1: Iterating over product lists

In an inventory system, you often need to loop through lists of products, perhaps to display them, calculate total inventory value, or update their status.

inventory management

For example

Consider an ArrayList of Product objects, where Product is a class representing items in your inventory.

ArrayList<Product> products = new ArrayList<>();

// Adding products to the list (skipped for brevity)

for (Product product : products) {
    System.out.println(product.getName() + " - " + product.getPrice());
}

The enhanced for loop makes it straightforward to access each Product object in the ArrayList.

It completely eliminates the need for an index variable and so reduces the risk of index-related errors. The code also becomes more intuitive and readable and is going to be of great help in maintaining our business applications.

Not bad eh!

Use Case 2: Processing customer data

In the same inventory system, managing customer data is equally important. This could involve iterating over a set of customer records to generate reports, send notifications, or update profiles.

For example

Suppose we have a HashSet of Customer objects, where Customer is a class encapsulating customer information.

HashSet<Customer> customers = new HashSet<>();

// Populating the HashSet (skipped for brevity)

for (Customer customer : customers) {
    System.out.println(customer.getName() + " - " + customer.getEmail());
}

Using the enhanced for loop with a HashSet like this demonstrates that we can use it with different types of collections.

Again, the enhanced for loop simplifies the process of iterating over a set where elements are unordered and unique. As a result, the code becomes cleaner and more focused on business logic rather than loop control mechanics.

Pretty cool, right?

So, let’s compare and contrast both of the loops next.

Enhanced foreach loop vs. traditional for loop

The enhanced for loop doesn’t eliminate the need for the traditional for loop, and so if you want to use either of them effectively, then you need to understand them both.

This section is going to give you a comparative overview, focusing on syntax, use cases, and when to prefer one over the other.

Feature Enhanced For Loop Traditional For Loop
Syntax for (Type item : collection) { ... } for (initialization; condition; update) { ... }
Element Access Direct access to each element. Access elements via index.
Use Case Ideal for iterating over arrays and collections. Suitable for complex iterations with index control.
Index Usage Index not directly accessible. Index is explicitly controlled and accessible.
Flexibility Limited to sequential iteration. Flexible, allows various iteration patterns.
Readability Higher due to simpler syntax. Lower, more complex due to manual index management.
Error Prone Less prone to errors like off-by-one. More prone to index-related errors.

After having seen this schematic compare and contrast overview, let’s talk about when to use each one.

When to use the enhanced for loop (foreach)

When your primary concern is to process each element in a collection or array and the index of the element is not required, the enhanced for loop is the way to go.

It's more readable and to the point, especially when dealing with collections where index management is not straightforward.

When to use the traditional for loop

In scenarios where you need to keep track of the index of elements, such as when accessing two arrays simultaneously or when the index is used in calculations, the traditional for loop is necessary.

Also, situations where you need to manipulate the loop counter, like skipping certain elements or changing the step size, require the traditional for loop.

Why?

Well, the traditional for loop offers more flexibility in terms of iteration patterns. It allows backward iteration, conditional continuation, and other complex patterns that are not possible with the enhanced for loop.

Let’s have a look at a scenario where we cannot use the enhanced foreach loop…

Situations favoring the traditional for loop

When index-based control is essential, we need to use the traditional for loop.

For example

In a financial reporting system, precision and custom calculations are often the norm. Also, these systems often require the manipulation of data, based on their position or relation to other data points.

Let’s say that we are given the task of generating a detailed expense report where each line item may need to be compared with previous entries, or calculations may depend on the position of the item in the list.

Here’s how to do that:

List<Expense> expenses = getMonthlyExpenses(); // Method to fetch expense data
double[] adjustments = getMonthlyAdjustments(); // Corresponding adjustments

for (int i = 0; i < expenses.size(); i++) {
    Expense expense = expenses.get(i);
    double adjustedAmount = expense.getAmount() + adjustments[i];
    System.out.println("Expense: " + expense.getDescription() + ", Adjusted Amount: " + adjustedAmount);
}

In this example, each Expense object in the List is processed alongside a corresponding adjustment value, stored in a parallel array.

This operation requires simultaneous access to both the expenses list and the adjustments array, which can only be achieved through index-based iteration.

Best practices and performance considerations

As you have seen, choosing between the enhanced and traditional for loops in Java is not just a matter of syntax preference but also involves considerations of what is possible with each of the two loops.

Let’s explore the best practices for selecting the right loop for your situation and tips for writing clean, efficient code.

Performance aspects of both loops

The enhanced for loop is optimized for iterating over collections and arrays.

This loop can lead to more efficient bytecode, especially in the case of collections. However, in scenarios where the loop's body is minimal, the overhead of the iterator (in collections) or the hidden index (in arrays) can slightly affect performance.

The traditional for loop offers tight control over the iteration process, which can be more performant in scenarios requiring complex index manipulations or non-sequential access patterns. The manual control of indices, however, can introduce performance overhead if not handled correctly, such as unnecessary recalculations or bounds checking.

tl;dr:

Generally speaking, it’s a best practice to use the enhanced foreach loop for straightforward iterations over arrays or collections where the index is not needed. While we should opt for the traditional for loop when dealing with parallel arrays or when specific index manipulation is required.

There’s also a (somewhat obvious) best practice that is true for both loops, and that is that it's best to avoid unnecessary calculations inside loops where possible to reduce computational load.

And as always, make sure to test for performance, and when in doubt (or when performance is very critical), do an a/b test between the traditional for and the enhanced foreach loop.

test your code speed

Let’s see one slightly more advanced example before wrapping up this article.

Advanced foreach usage example

By now you should be fairly comfortable with the basic usage of the enhanced for loop, so let’s see if we can push it a little and expand beyond the basics.

How?

Let’s use enhanced foreach loops combined with multidimensional arrays.

This requires a nested approach.

For example

Here’s how you can iterate through a two-dimensional array:

int[][] matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

for (int[] row : matrix) {
    for (int element : row) {
        System.out.print(element + " ");
    }
    System.out.println();
}

In this example, the outer loop iterates over each row (which is itself an array), and the inner loop iterates over each element within that row.

Alright, and that’s it. Let’s go over the most important points and wrap up.

Phew! Did you get all that?

And that’s it for the enhanced for loop.

I know we covered quite a few things here, so hopefully you managed to grasp what we've been talking about.

To summarize:

  • The enhanced for loop (also known as a foreach) loop in Java offers a simplified, error-resistant way to iterate over arrays and collections
  • The traditional for loop is still needed for index-based operations and complex iteration patterns
  • Performance considerations, readability, and the specific requirements of the task should guide the choice of loop
  • Advanced techniques, like using the enhanced for loop with multidimensional arrays can address more complex scenarios effectively
  • In order to find out which approach is best, I encourage you to experiment with both loops and measure the difference in performance
  • Both the enhanced and traditional for loops have their place in Java programming. Experimenting with both, understanding their nuances, and knowing when to use each one will up your Java skills.

If in doubt, always aim for code that not only works but is also well-structured and intuitive for others (and your future self) to understand. Keep that in mind, and you’ll pick these techniques up in no time!

P.S

Be sure to check out my complete Java programming course here or watch the first few videos for free if you struggled with anything in this post, or simply want to improve your Java skills.

The course will teach you Java coding from scratch, solidify your knowledge with exercises, help you build fun projects, and gain the skills you need to get hired as a Java Developer in 2024!

No prior programming knowledge is required. Just a willingness and enthusiasm to learn Java.

And better still? When you join the course, not only do you have access to all the training content, but you can also ask questions of me and other Java Developers inside our private Discord channel, so you’ll never be stuck for long!

More from Zero To Mastery

Stack Memory In Java: Beginner's Guide (With Code Examples) preview
Stack Memory In Java: Beginner's Guide (With Code Examples)

Understanding memory management is a vital skill for any Java Developer. In this guide, I break down Stack Memory, how it works, its limitations, and more!

12 Entry-Level Tech Jobs To Kick-Start Your New Career preview
12 Entry-Level Tech Jobs To Kick-Start Your New Career

Get your foot in the door with 4 roles that require zero experience, and 8 more that just require some self-taught education. ($5 + $6-figure salaries!)

Don’t be a Junior Developer: The Roadmap From Junior to Senior preview
Popular
Don’t be a Junior Developer: The Roadmap From Junior to Senior

Don’t sell yourself short. Seriously, don’t be a Junior Developer. This article outlines all the skills that you should learn if you want to get out of your Junior Developer role and get started on the path to becoming a Senior Developer.