Iterating over the elements of a list is one of the most common tasks in a program. This tutorial will explore various approaches to accomplish this task in Java. Our primary focus will be on iterating through the list in its original order, but we’ll also touch on the straightforward process of traversing it in reverse.
Here are different ways to iterate through an ArrayList
Let’s assume we have a simple banking system with a list of bank accounts. Each bank account has a balance, an account number, and a customer’s name. We will use the different Java features to iterate over this list of bank accounts in various ways.
import java.util.ArrayList;
import java.util.List;
public class BankAccount {
private int accountNumber;
private String customerName;
private double balance;
public BankAccount(int accountNumber, String customerName, double balance) {
this.accountNumber = accountNumber;
this.customerName = customerName;
this.balance = balance;
}
// Getters and Setters
public int getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(int accountNumber) {
this.accountNumber = accountNumber;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public static void main(String[] args) {
List accounts = new ArrayList<>();
accounts.add(new BankAccount(12345, "John Doe", 1000.0));
accounts.add(new BankAccount(67890, "Jane Smith", 5000.0));
accounts.add(new BankAccount(13579, "Bob Johnson", 2000.0));
}
}
forEach() :
The forEach()
method of the Stream API allows us to perform an action on each element of the ArrayList.
System.out.println("Using forEach():");
accounts.forEach(account -> {
System.out.println("Account Number: " + account.getAccountNumber() +
", Customer Name: " + account.getCustomerName() +
", Balance: " + account.getBalance());
});
for-each loop with Stream:
We can convert the ArrayList into a stream and then use the for-each loop to iterate over it.
System.out.println("Using for-each loop with Stream:");
accounts.stream().forEach(account -> {
System.out.println("Account Number: " + account.getAccountNumber() +
", Customer Name: " + account.getCustomerName() +
", Balance: " + account.getBalance());
});
Method references:
We can also use method references to simplify the code further.
System.out.println("Using method references:");
accounts.forEach(BankAccount::printAccountInfo);
// Helper method for method reference example
public void printAccountInfo() {
System.out.println("Account Number: " + accountNumber +
", Customer Name: " + customerName +
", Balance: " + balance);
}
ParallelStream():
If we have a large collection and want to perform operations in parallel, we can use the parallelStream()
method to utilize multiple cores of the CPU.
Note: While using parallelStream()
can speed up processing for large collections, it’s important to consider potential thread safety issues in our code. Always ensure that the operations performed on the ArrayList are thread-safe when using parallelStream(). For simple iterations like the ones shown in these examples, using the regular stream is generally sufficient.
System.out.println("Using parallelStream():");
accounts.parallelStream().forEach(account -> {
System.out.println("Account Number: " + account.getAccountNumber() +
", Customer Name: " + account.getCustomerName() +
", Balance: " + account.getBalance());
});
ListIterator:
The ListIterator
in Java provides a bidirectional iteration over a list, allowing us to traverse elements in both forward and backward directions. Here’s an example using the ListIterator
to iterate over a list of bank accounts:
// Using ListIterator to iterate forward
System.out.println("Using ListIterator to iterate forward:");
ListIterator forwardIterator = accounts.listIterator();
while (forwardIterator.hasNext()) {
BankAccount account = forwardIterator.next();
System.out.println("Account Number: " + account.getAccountNumber() +
", Customer Name: " + account.getCustomerName() +
", Balance: " + account.getBalance());
}
// Using ListIterator to iterate backward
System.out.println("Using ListIterator to iterate backward:");
ListIterator backwardIterator = accounts.listIterator(accounts.size());
while (backwardIterator.hasPrevious()) {
BankAccount account = backwardIterator.previous();
System.out.println("Account Number: " + account.getAccountNumber() +
", Customer Name: " + account.getCustomerName() +
", Balance: " + account.getBalance());
}
In this example, we create a list of bank accounts and then use two ListIterator
instances: one to iterate forward and another to iterate backward. The forward iterator traverses the list using next()
and the backward iterator uses previous()
. This allows us to iterate over the list of bank accounts in both directions.
Basic for loop:
This is the simplest way to iterate through an ArrayList. We can use a for loop to iterate over the elements of the ArrayList and access them one by one.
// Basic for loop
System.out.println("Iterating using Basic For Loop:");
for (int i = 0; i < bankAccounts.size(); i++) {
BankAccount account = bankAccounts.get(i);
System.out.println(account);
}
For-each loop:
The for-each loop is a special type of for loop that is designed for iterating over collections. We can use a for-each loop to iterate over the elements of an ArrayList without having to worry about the index of each element.
// Enhanced for loop (foreach loop)
System.out.println("Iterating using Enhanced For Loop (Foreach):");
for (BankAccount account : bankAccounts) {
System.out.println(account);
}
These are just a few of the different ways to iterate through an ArrayList in Java. The best way to iterate through an ArrayList will depend on the specific task that we are trying to accomplish.