Java 10 – Using var with ArrayList and Five Ways to Iterate
ArrayList is the most commonly used collection in Java, and Java 10's var keyword makes working with it even cleaner. This tutorial demonstrates how to declare an ArrayList using var and iterate over it using five different techniques — from traditional for loops to the modern Stream API.
Understanding multiple iteration strategies matters in practice: some approaches support removal during iteration, some are better for parallel processing, and some are more readable. By the end of this post, you will know which method to choose for each situation.
Prerequisites
- Java 10 or later
- Basic knowledge of Java lists and generics
- Familiarity with Java 8 lambda syntax (optional but helpful)
Complete Example
package com.java9r;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Java 10 – ArrayList declared with var, iterated five ways.
* Each method has different trade-offs for real-world use.
*/
public class Java10ArrayListWithVar {
public static void main(String[] args) {
// var infers ArrayList<String> from the initializer
var products = new ArrayList<String>();
products.add("Laptop");
products.add("Smartphone");
products.add("Tablet");
products.add("Monitor");
products.add("Keyboard");
System.out.println("Total products: " + products.size());
System.out.println();
// -------------------------------------------------------
// Method 1 : Classic index-based for loop
// Use when you need the index value (e.g., to display row numbers)
// -------------------------------------------------------
System.out.println("1) Index-based for loop:");
for (var i = 0; i < products.size(); i++) {
System.out.println(" [" + (i + 1) + "] " + products.get(i));
}
// -------------------------------------------------------
// Method 2 : Enhanced for-each loop
// Cleanest syntax; use for simple read-only iteration
// -------------------------------------------------------
System.out.println("\n2) Enhanced for-each:");
for (var product : products) {
System.out.println(" " + product);
}
// -------------------------------------------------------
// Method 3 : Iterator
// Use when you need to remove elements during iteration
// -------------------------------------------------------
System.out.println("\n3) Iterator:");
Iterator<String> iterator = products.iterator();
while (iterator.hasNext()) {
var product = iterator.next();
System.out.println(" " + product);
}
// -------------------------------------------------------
// Method 4 : forEach() with lambda (Java 8+)
// Concise; good for logging, printing, or simple transforms
// -------------------------------------------------------
System.out.println("\n4) forEach() with lambda:");
products.forEach(product -> System.out.println(" " + product));
// -------------------------------------------------------
// Method 5 : Stream API with filter (Java 8+)
// Best when you need to filter, map, or collect results
// -------------------------------------------------------
System.out.println("\n5) Stream API – items containing 'a':");
products.stream()
.filter(p -> p.toLowerCase().contains("a"))
.sorted()
.forEach(p -> System.out.println(" " + p));
}
}
Expected Output
Total products: 5
1) Index-based for loop:
[1] Laptop
[2] Smartphone
[3] Tablet
[4] Monitor
[5] Keyboard
2) Enhanced for-each:
Laptop
Smartphone
Tablet
Monitor
Keyboard
3) Iterator:
Laptop
Smartphone
Tablet
Monitor
Keyboard
4) forEach() with lambda:
Laptop
Smartphone
Tablet
Monitor
Keyboard
5) Stream API – items containing 'a':
Keyboard
Laptop
Smartphone
Tablet
Removing Items Safely During Iteration
One common pitfall is calling list.remove() inside a for-each loop. This throws a ConcurrentModificationException. The safe approach is to use Iterator.remove() or removeIf():
// Approach A: Iterator.remove() – classic safe removal
var iter = products.iterator();
while (iter.hasNext()) {
var p = iter.next();
if (p.startsWith("S")) {
iter.remove(); // removes "Smartphone" safely
}
}
// Approach B: removeIf() – Java 8+, cleaner syntax
products.removeIf(p -> p.startsWith("S"));
Collecting a Filtered List with Stream API
import java.util.stream.Collectors;
// Collect products whose name is longer than 6 characters
var longNames = products.stream()
.filter(p -> p.length() > 6)
.collect(Collectors.toList());
System.out.println("Long product names: " + longNames);
// Output: Long product names: [Smartphone, Monitor, Keyboard]
var Saves the Most with Complex Generic Types
// Without var – very verbose
ArrayList<HashMap<String, List<Integer>>> data = new ArrayList<>();
// With var – clean
var data = new ArrayList<HashMap<String, List<Integer>>>();
Comparison Table
| Method | Index Access | Safe Removal | Filter/Map | Parallel |
|---|---|---|---|---|
| Index for loop | Yes | With care | No | No |
| Enhanced for-each | No | No | No | No |
| Iterator | No | Yes | No | No |
| forEach lambda | No | No | No | No |
| Stream API | No | No | Yes | Yes (parallelStream) |
Summary
Java 10's var makes ArrayList declarations more concise, especially with deeply nested generics. For most day-to-day list iteration, the enhanced for-each loop is the clearest choice. When you need to remove elements during the loop, switch to Iterator or removeIf(). For filtering, sorting, or collecting results, the Stream API is the most powerful option. All five methods produce identical results for plain sequential reads — choose based on what additional operations you need.
Comments