Java ProgramsCollectionsArrayList Iteration

ArrayList Iteration in Java

beginner·  Collections  ·  List

Problem

An ArrayList can be visited with a for-each loop, an explicit Iterator, or a plain index-based loop — all three reach the same elements in the same order, just through different mechanics.

Given an ArrayList of fruits, print its contents three times using a for-each loop, an Iterator, and an index-based loop.

Input
add("Apple"), add("Banana"), add("Cherry")
Output
For-each loop: Apple, Banana, Cherry ...

Java Program

Java
import java.util.ArrayList; import java.util.Iterator; public class ArrayListIteration { public static void main(String[] args) { ArrayList<String> fruits = new ArrayList<>(); fruits.add("Apple"); fruits.add("Banana"); fruits.add("Cherry"); System.out.println("For-each loop:"); for (String fruit : fruits) { System.out.println(fruit); } System.out.println("Iterator:"); Iterator<String> it = fruits.iterator(); while (it.hasNext()) { System.out.println(it.next()); } System.out.println("Index-based loop:"); for (int i = 0; i < fruits.size(); i++) { System.out.println(fruits.get(i)); } } }

Output

For-each loop: Apple Banana Cherry Iterator: Apple Banana Cherry Index-based loop: Apple Banana Cherry

Core Logic

The for-each loop and the explicit Iterator it's built on both walk forward automatically, while the index-based loop reaches each element by asking for it directly at a given position.

How It Works
  1. 1The for-each loop (for (String fruit : fruits)) is syntactic sugar — under the hood, it creates an Iterator and calls hasNext()/next() for you.
  2. 2The explicit Iterator<String> it = fruits.iterator(); loop does the exact same thing by hand, calling hasNext() to check for more elements and next() to advance and retrieve one.
  3. 3The index-based loop instead calls fruits.get(i) directly for each index from 0 to size() - 1, needing no iterator object at all.
  4. 4All three visit Apple, Banana, and Cherry in that same order, since ArrayList preserves insertion order.
Each of the three loops prints the same three fruits in the same order — the difference is purely in how each one reaches the next element, not what it finds.
💡

Key Point: An explicit Iterator is the one style that safely supports removing elements mid-loop via it.remove() — modifying the list directly during a for-each or index-based loop risks a ConcurrentModificationException or skipped elements.

Complexity
Time Complexity: O(n)Space Complexity: O(1)

Why: Each style visits all n elements exactly once; the for-each loop and explicit Iterator both use the same constant-space iterator object internally, and the index-based loop needs only a single counter variable.

Key Concepts

ArrayListfor-each loopIteratorindex-based loop

Approach 2: Java 8

Java
import java.util.ArrayList; public class ArrayListIterationStream { public static void main(String[] args) { ArrayList<String> fruits = new ArrayList<>(); fruits.add("Apple"); fruits.add("Banana"); fruits.add("Cherry"); System.out.println("Stream forEach:"); // No explicit loop construct — the pipeline drives the traversal itself fruits.stream().forEach(System.out::println); } }

Output

Stream forEach: Apple Banana Cherry

Core Logic

A stream's forEach() offers a fourth way to walk the list — a declarative pipeline instead of an explicit loop of any kind.

How It Works
  1. 1fruits.stream() opens a stream over the list's elements, in the same order the list itself holds them.
  2. 2.forEach(System.out::println) passes a method reference that runs once per element, printing it.
  3. 3Unlike the other three styles, there's no visible loop construct at all — no for, no while, no Iterator variable.
  4. 4The result still visits Apple, Banana, and Cherry in that same order, since streams over a List preserve encounter order by default.
Streaming [Apple, Banana, Cherry] and calling forEach(System.out::println) prints the same three fruits in the same order as the other three styles.
💡

Key Point: This is the one style that can't safely remove elements mid-traversal at all — not even the explicit-Iterator way; forEach() is read-only by design, so mutation still belongs to the Iterator style shown in the primary approach.

Complexity
Time Complexity: O(n)Space Complexity: O(1)

Why: forEach() still visits each of the n elements exactly once, using a constant amount of extra state to drive the stream.

Key Concepts

StreamforEach()method reference

Related Programs