Iterator and ListIterator in Java: Complete Guide

Table of Contents

  1. Introduction to Iterators
  2. Iterator Interface
  3. ListIterator Interface
  4. Comparison: Iterator vs ListIterator
  5. Implementation Examples
  6. Fail-Fast vs Fail-Safe Iterators
  7. Custom Iterator Implementation
  8. Best Practices
  9. Real-World Examples

Introduction to Iterators

Iterators provide a way to traverse through collections in Java. They offer a standardized approach to access elements sequentially without exposing the underlying collection structure.

Why Use Iterators?

  • Uniform access to different collection types
  • Safe element removal during iteration
  • Bidirectional traversal (with ListIterator)
  • Separation of concerns between traversal logic and collection implementation

Iterator Interface

Basic Iterator Methods

public interface Iterator<E> {
boolean hasNext();    // Returns true if more elements exist
E next();            // Returns the next element
void remove();       // Removes the last element returned by next()
}

Basic Iterator Usage

import java.util.*;
public class BasicIteratorDemo {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
fruits.add("Mango");
System.out.println("=== Basic Iterator Traversal ===");
// Get iterator instance
Iterator<String> iterator = fruits.iterator();
// Traverse using iterator
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println("Fruit: " + fruit);
}
}
}

Iterator with Removal

import java.util.*;
public class IteratorRemovalDemo {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
numbers.add(i);
}
System.out.println("Original list: " + numbers);
// Remove even numbers using iterator
Iterator<Integer> iterator = numbers.iterator();
while (iterator.hasNext()) {
Integer number = iterator.next();
if (number % 2 == 0) {
iterator.remove(); // Safe removal during iteration
}
}
System.out.println("After removing even numbers: " + numbers);
}
}

Iterator with Different Collection Types

import java.util.*;
public class IteratorWithCollections {
public static void main(String[] args) {
System.out.println("=== Iterator with Different Collections ===");
// ArrayList
List<String> arrayList = Arrays.asList("A", "B", "C", "D");
System.out.println("ArrayList iteration:");
iterateCollection(arrayList);
// HashSet
Set<String> hashSet = new HashSet<>(Arrays.asList("X", "Y", "Z"));
System.out.println("\nHashSet iteration:");
iterateCollection(hashSet);
// LinkedList
Queue<String> linkedList = new LinkedList<>(Arrays.asList("P", "Q", "R"));
System.out.println("\nLinkedList iteration:");
iterateCollection(linkedList);
}
public static void iterateCollection(Collection<String> collection) {
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}

ListIterator Interface

ListIterator Methods

public interface ListIterator<E> extends Iterator<E> {
// Forward operations (from Iterator)
boolean hasNext();
E next();
// Backward operations
boolean hasPrevious();
E previous();
// Index operations
int nextIndex();
int previousIndex();
// Modification operations
void remove();
void set(E e);
void add(E e);
}

Basic ListIterator Usage

import java.util.*;
public class BasicListIteratorDemo {
public static void main(String[] args) {
List<String> colors = new ArrayList<>();
colors.add("Red");
colors.add("Green");
colors.add("Blue");
colors.add("Yellow");
System.out.println("=== ListIterator Bidirectional Traversal ===");
// Get ListIterator
ListIterator<String> listIterator = colors.listIterator();
System.out.println("Forward traversal:");
while (listIterator.hasNext()) {
String color = listIterator.next();
System.out.println("Color: " + color + " [Index: " + listIterator.nextIndex() + "]");
}
System.out.println("\nBackward traversal:");
while (listIterator.hasPrevious()) {
String color = listIterator.previous();
System.out.println("Color: " + color + " [Index: " + listIterator.previousIndex() + "]");
}
}
}

ListIterator Modification Operations

import java.util.*;
public class ListIteratorModificationDemo {
public static void main(String[] args) {
List<String> cities = new ArrayList<>();
Collections.addAll(cities, "New York", "London", "Tokyo", "Paris");
System.out.println("Original list: " + cities);
ListIterator<String> iterator = cities.listIterator();
// Modify elements during iteration
while (iterator.hasNext()) {
String city = iterator.next();
if (city.equals("London")) {
iterator.set("LONDON"); // Replace element
}
if (city.equals("Tokyo")) {
iterator.add("Sydney"); // Add element after current position
}
}
System.out.println("After modifications: " + cities);
// Remove specific elements
iterator = cities.listIterator();
while (iterator.hasNext()) {
String city = iterator.next();
if (city.length() <= 5) {
iterator.remove(); // Remove short city names
}
}
System.out.println("After removal: " + cities);
}
}

Comparison: Iterator vs ListIterator

Feature Comparison Table

FeatureIteratorListIterator
Traversal DirectionForward onlyBidirectional
Element AccessSequentialSequential with indices
Element ModificationRemove onlyRemove, Add, Set
Collection TypesAll CollectionsOnly Lists
Index InformationNoYes (nextIndex, previousIndex)

Side-by-Side Comparison

import java.util.*;
public class IteratorVsListIterator {
public static void main(String[] args) {
List<String> data = Arrays.asList("A", "B", "C", "D", "E");
System.out.println("=== Iterator vs ListIterator Comparison ===");
// Iterator demonstration
System.out.println("\n--- Iterator (Forward only) ---");
Iterator<String> iterator = data.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
// ListIterator demonstration
System.out.println("\n\n--- ListIterator (Bidirectional) ---");
ListIterator<String> listIterator = data.listIterator();
System.out.print("Forward: ");
while (listIterator.hasNext()) {
System.out.print(listIterator.next() + " ");
}
System.out.print("\nBackward: ");
while (listIterator.hasPrevious()) {
System.out.print(listIterator.previous() + " ");
}
// ListIterator additional features
System.out.println("\n\n--- ListIterator Extra Features ---");
listIterator = data.listIterator();
while (listIterator.hasNext()) {
String element = listIterator.next();
int nextIndex = listIterator.nextIndex();
System.out.println("Element: " + element + ", Next Index: " + nextIndex);
// Modify elements
if (element.equals("C")) {
listIterator.set("C-MODIFIED");
}
}
System.out.println("Modified list: " + data);
}
}

Implementation Examples

Practical Iterator Patterns

import java.util.*;
public class PracticalIteratorPatterns {
// Pattern 1: Filter elements during iteration
public static <T> List<T> filterList(List<T> list, java.util.function.Predicate<T> predicate) {
List<T> result = new ArrayList<>();
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
T element = iterator.next();
if (predicate.test(element)) {
result.add(element);
}
}
return result;
}
// Pattern 2: Transform elements during iteration
public static <T, R> List<R> transformList(List<T> list, java.util.function.Function<T, R> function) {
List<R> result = new ArrayList<>();
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
T element = iterator.next();
result.add(function.apply(element));
}
return result;
}
// Pattern 3: Find element with custom condition
public static <T> Optional<T> findElement(List<T> list, java.util.function.Predicate<T> predicate) {
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
T element = iterator.next();
if (predicate.test(element)) {
return Optional.of(element);
}
}
return Optional.empty();
}
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println("Original numbers: " + numbers);
// Filter even numbers
List<Integer> evenNumbers = filterList(numbers, n -> n % 2 == 0);
System.out.println("Even numbers: " + evenNumbers);
// Transform numbers to their squares
List<Integer> squares = transformList(numbers, n -> n * n);
System.out.println("Squares: " + squares);
// Find first number greater than 5
Optional<Integer> found = findElement(numbers, n -> n > 5);
found.ifPresent(n -> System.out.println("First number > 5: " + n));
}
}

Advanced ListIterator Usage

import java.util.*;
public class AdvancedListIteratorDemo {
// Reverse a list using ListIterator
public static <T> void reverseList(List<T> list) {
ListIterator<T> forward = list.listIterator();
ListIterator<T> backward = list.listIterator(list.size());
for (int i = 0; i < list.size() / 2; i++) {
T temp = forward.next();
forward.set(backward.previous());
backward.set(temp);
}
}
// Merge two sorted lists
public static <T extends Comparable<T>> List<T> mergeSortedLists(List<T> list1, List<T> list2) {
List<T> result = new ArrayList<>();
ListIterator<T> iter1 = list1.listIterator();
ListIterator<T> iter2 = list2.listIterator();
T elem1 = iter1.hasNext() ? iter1.next() : null;
T elem2 = iter2.hasNext() ? iter2.next() : null;
while (elem1 != null || elem2 != null) {
if (elem1 == null) {
result.add(elem2);
elem2 = iter2.hasNext() ? iter2.next() : null;
} else if (elem2 == null) {
result.add(elem1);
elem1 = iter1.hasNext() ? iter1.next() : null;
} else if (elem1.compareTo(elem2) <= 0) {
result.add(elem1);
elem1 = iter1.hasNext() ? iter1.next() : null;
} else {
result.add(elem2);
elem2 = iter2.hasNext() ? iter2.next() : null;
}
}
return result;
}
// Find all occurrences and their indices
public static <T> Map<T, List<Integer>> findElementIndices(List<T> list) {
Map<T, List<Integer>> indices = new HashMap<>();
ListIterator<T> iterator = list.listIterator();
while (iterator.hasNext()) {
int index = iterator.nextIndex();
T element = iterator.next();
indices.computeIfAbsent(element, k -> new ArrayList<>()).add(index);
}
return indices;
}
public static void main(String[] args) {
// Test reverse
List<String> words = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
System.out.println("Original: " + words);
reverseList(words);
System.out.println("Reversed: " + words);
// Test merge
List<Integer> list1 = Arrays.asList(1, 3, 5, 7);
List<Integer> list2 = Arrays.asList(2, 4, 6, 8);
List<Integer> merged = mergeSortedLists(list1, list2);
System.out.println("Merged: " + merged);
// Test indices
List<String> elements = Arrays.asList("A", "B", "A", "C", "B", "A");
Map<String, List<Integer>> indices = findElementIndices(elements);
System.out.println("Element indices: " + indices);
}
}

Fail-Fast vs Fail-Safe Iterators

Fail-Fast Iterators

import java.util.*;
public class FailFastIteratorDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "A", "B", "C", "D");
System.out.println("=== Fail-Fast Iterator Demo ===");
// This will throw ConcurrentModificationException
try {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println("Processing: " + element);
if (element.equals("B")) {
list.add("E"); // Structural modification
}
}
} catch (ConcurrentModificationException e) {
System.out.println("ConcurrentModificationException caught: " + e.getMessage());
}
// Safe way to modify during iteration
System.out.println("\n=== Safe Modification ===");
List<String> safeList = new ArrayList<>();
Collections.addAll(safeList, "A", "B", "C", "D");
Iterator<String> safeIterator = safeList.iterator();
List<String> toAdd = new ArrayList<>();
while (safeIterator.hasNext()) {
String element = safeIterator.next();
System.out.println("Processing: " + element);
if (element.equals("B")) {
toAdd.add("E"); // Collect elements to add later
}
if (element.equals("C")) {
safeIterator.remove(); // Safe removal using iterator
}
}
// Add collected elements after iteration
safeList.addAll(toAdd);
System.out.println("Final list: " + safeList);
}
}

Fail-Safe Iterators (CopyOnWriteArrayList)

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class FailSafeIteratorDemo {
public static void main(String[] args) {
// CopyOnWriteArrayList is fail-safe
List<String> list = new CopyOnWriteArrayList<>();
Collections.addAll(list, "A", "B", "C", "D");
System.out.println("=== Fail-Safe Iterator Demo ===");
Iterator<String> iterator = list.iterator();
// Modify list while iterating (won't throw exception)
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println("Processing: " + element);
if (element.equals("B")) {
list.add("E"); // Structural modification
list.remove("A"); // Another modification
}
}
System.out.println("List after modifications: " + list);
System.out.println("Note: Iterator didn't see the modifications!");
// New iterator will see the changes
System.out.println("\nNew iteration with new iterator:");
iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println("Element: " + iterator.next());
}
}
}

Concurrent Modification Scenarios

import java.util.*;
public class ConcurrentModificationScenarios {
public static void main(String[] args) {
System.out.println("=== Concurrent Modification Scenarios ===");
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
// Scenario 1: Direct modification - THROWS EXCEPTION
try {
Iterator<String> iter1 = list.iterator();
while (iter1.hasNext()) {
String element = iter1.next();
if (element.equals("B")) {
list.remove("B"); // Direct modification
}
}
} catch (ConcurrentModificationException e) {
System.out.println("Scenario 1: Direct modification - EXCEPTION");
}
// Scenario 2: Iterator removal - WORKS FINE
List<String> list2 = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
Iterator<String> iter2 = list2.iterator();
while (iter2.hasNext()) {
String element = iter2.next();
if (element.equals("B")) {
iter2.remove(); // Iterator removal - SAFE
}
}
System.out.println("Scenario 2: Iterator removal - SUCCESS: " + list2);
// Scenario 3: Modification after iterator creation - THROWS EXCEPTION
try {
List<String> list3 = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
Iterator<String> iter3 = list3.iterator();
list3.add("E"); // Modification after iterator creation
iter3.next(); // This will throw exception
} catch (ConcurrentModificationException e) {
System.out.println("Scenario 3: Modification after iterator - EXCEPTION");
}
}
}

Custom Iterator Implementation

Building a Custom Collection with Iterator

import java.util.*;
class FixedSizeCollection<E> implements Iterable<E> {
private final E[] elements;
private int size;
@SuppressWarnings("unchecked")
public FixedSizeCollection(int capacity) {
this.elements = (E[]) new Object[capacity];
this.size = 0;
}
public boolean add(E element) {
if (size < elements.length) {
elements[size++] = element;
return true;
}
return false;
}
public E get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
return elements[index];
}
public int size() {
return size;
}
@Override
public Iterator<E> iterator() {
return new FixedSizeIterator();
}
// Custom Iterator implementation
private class FixedSizeIterator implements Iterator<E> {
private int currentIndex = 0;
private boolean removeCalled = false;
@Override
public boolean hasNext() {
return currentIndex < size;
}
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
removeCalled = false;
return elements[currentIndex++];
}
@Override
public void remove() {
if (currentIndex == 0 || removeCalled) {
throw new IllegalStateException();
}
// Shift elements to remove current element
for (int i = currentIndex - 1; i < size - 1; i++) {
elements[i] = elements[i + 1];
}
elements[--size] = null;
currentIndex--;
removeCalled = true;
}
}
}
public class CustomIteratorDemo {
public static void main(String[] args) {
FixedSizeCollection<String> collection = new FixedSizeCollection<>(5);
collection.add("Apple");
collection.add("Banana");
collection.add("Cherry");
collection.add("Date");
System.out.println("=== Custom Iterator Demo ===");
// Using enhanced for-loop (uses our iterator)
for (String fruit : collection) {
System.out.println("Fruit: " + fruit);
}
// Using iterator directly
System.out.println("\nUsing iterator directly:");
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println("Fruit: " + fruit);
if (fruit.equals("Banana")) {
iterator.remove(); // Use our custom remove
}
}
System.out.println("\nAfter removal:");
for (String fruit : collection) {
System.out.println("Fruit: " + fruit);
}
}
}

Custom ListIterator Implementation

import java.util.*;
class CircularList<E> implements List<E> {
private final List<E> elements;
public CircularList() {
this.elements = new ArrayList<>();
}
public CircularList(Collection<? extends E> c) {
this.elements = new ArrayList<>(c);
}
@Override
public ListIterator<E> listIterator() {
return new CircularListIterator(0);
}
@Override
public ListIterator<E> listIterator(int index) {
return new CircularListIterator(index);
}
// Other List methods would be implemented here...
@Override public int size() { return elements.size(); }
@Override public boolean isEmpty() { return elements.isEmpty(); }
@Override public boolean contains(Object o) { return elements.contains(o); }
@Override public Iterator<E> iterator() { return elements.iterator(); }
@Override public Object[] toArray() { return elements.toArray(); }
@Override public <T> T[] toArray(T[] a) { return elements.toArray(a); }
@Override public boolean add(E e) { return elements.add(e); }
@Override public boolean remove(Object o) { return elements.remove(o); }
@Override public boolean containsAll(Collection<?> c) { return elements.containsAll(c); }
@Override public boolean addAll(Collection<? extends E> c) { return elements.addAll(c); }
@Override public boolean addAll(int index, Collection<? extends E> c) { return elements.addAll(index, c); }
@Override public boolean removeAll(Collection<?> c) { return elements.removeAll(c); }
@Override public boolean retainAll(Collection<?> c) { return elements.retainAll(c); }
@Override public void clear() { elements.clear(); }
@Override public E get(int index) { return elements.get(index); }
@Override public E set(int index, E element) { return elements.set(index, element); }
@Override public void add(int index, E element) { elements.add(index, element); }
@Override public E remove(int index) { return elements.remove(index); }
@Override public int indexOf(Object o) { return elements.indexOf(o); }
@Override public int lastIndexOf(Object o) { return elements.lastIndexOf(o); }
@Override public List<E> subList(int fromIndex, int toIndex) { return elements.subList(fromIndex, toIndex); }
// Custom Circular ListIterator
private class CircularListIterator implements ListIterator<E> {
private int currentPosition;
private int lastReturned = -1;
private int direction = 0; // 0=initial, 1=forward, -1=backward
public CircularListIterator(int index) {
this.currentPosition = index % (elements.size() + 1);
}
@Override
public boolean hasNext() {
return !elements.isEmpty(); // Always true for circular list
}
@Override
public E next() {
if (elements.isEmpty()) {
throw new NoSuchElementException();
}
E element = elements.get(currentPosition);
lastReturned = currentPosition;
currentPosition = (currentPosition + 1) % elements.size();
direction = 1;
return element;
}
@Override
public boolean hasPrevious() {
return !elements.isEmpty(); // Always true for circular list
}
@Override
public E previous() {
if (elements.isEmpty()) {
throw new NoSuchElementException();
}
currentPosition = (currentPosition - 1 + elements.size()) % elements.size();
E element = elements.get(currentPosition);
lastReturned = currentPosition;
direction = -1;
return element;
}
@Override
public int nextIndex() {
return currentPosition;
}
@Override
public int previousIndex() {
return (currentPosition - 1 + elements.size()) % elements.size();
}
@Override
public void remove() {
if (lastReturned == -1) {
throw new IllegalStateException();
}
elements.remove(lastReturned);
if (lastReturned < currentPosition) {
currentPosition--;
}
currentPosition %= elements.size();
lastReturned = -1;
}
@Override
public void set(E e) {
if (lastReturned == -1) {
throw new IllegalStateException();
}
elements.set(lastReturned, e);
}
@Override
public void add(E e) {
elements.add(currentPosition, e);
currentPosition++;
lastReturned = -1;
}
}
}
public class CustomListIteratorDemo {
public static void main(String[] args) {
CircularList<String> circularList = new CircularList<>(
Arrays.asList("A", "B", "C", "D")
);
System.out.println("=== Custom Circular ListIterator ===");
ListIterator<String> iterator = circularList.listIterator();
System.out.println("First 10 elements (circular):");
for (int i = 0; i < 10; i++) {
System.out.print(iterator.next() + " ");
}
System.out.println("\n\nPrevious 5 elements:");
for (int i = 0; i < 5; i++) {
System.out.print(iterator.previous() + " ");
}
}
}

Best Practices

Iterator Best Practices

import java.util.*;
public class IteratorBestPractices {
// 1. Always check hasNext() before next()
public static void safeIteration(List<String> list) {
Iterator<String> iterator = list.iterator();
// CORRECT: Check hasNext() first
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
// INCORRECT: This can throw NoSuchElementException
// while (true) {
//     String element = iterator.next(); // Dangerous!
//     System.out.println(element);
// }
}
// 2. Use iterator.remove() for safe removal
public static void safeRemoval(List<Integer> list) {
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer number = iterator.next();
if (number % 2 == 0) {
iterator.remove(); // SAFE: Uses iterator's remove method
}
}
// DANGEROUS: Modifying list directly during iteration
// for (Integer number : list) {
//     if (number % 2 == 0) {
//         list.remove(number); // ConcurrentModificationException!
//     }
// }
}
// 3. Use for-each loop when you don't need to remove elements
public static void forEachBestPractice(List<String> list) {
// GOOD: Simple iteration without removal
for (String element : list) {
System.out.println(element);
}
// BETTER: When you need removal capability
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
if (element.startsWith("A")) {
iterator.remove();
}
}
}
// 4. Prefer ListIterator for List operations
public static void listIteratorBestPractice(List<String> list) {
ListIterator<String> listIterator = list.listIterator();
// Bidirectional traversal
while (listIterator.hasNext()) {
String element = listIterator.next();
if (element.equals("Target")) {
// Can go back and modify
listIterator.previous();
listIterator.set("Modified Target");
listIterator.next();
}
}
}
// 5. Avoid concurrent modifications
public static void avoidConcurrentModification() {
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
// SAFE: Collect modifications and apply later
List<String> toRemove = new ArrayList<>();
List<String> toAdd = new ArrayList<>();
for (String element : list) {
if (element.equals("B")) {
toRemove.add(element);
toAdd.add("B-New");
}
}
list.removeAll(toRemove);
list.addAll(toAdd);
System.out.println("Safe modification result: " + list);
}
// 6. Use appropriate iterator for the collection type
public static void chooseRightIterator() {
List<String> arrayList = new ArrayList<>();
Set<String> hashSet = new HashSet<>();
Map<String, Integer> hashMap = new HashMap<>();
// List: Use ListIterator for bidirectional access
ListIterator<String> listIter = arrayList.listIterator();
// Set: Use Iterator (only forward)
Iterator<String> setIter = hashSet.iterator();
// Map: Iterate over entrySet, keySet, or values
Iterator<Map.Entry<String, Integer>> mapIter = hashMap.entrySet().iterator();
System.out.println("Using appropriate iterators for each collection type");
}
public static void main(String[] args) {
List<String> sampleList = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
List<Integer> numberList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
safeIteration(sampleList);
safeRemoval(numberList);
forEachBestPractice(sampleList);
listIteratorBestPractice(sampleList);
avoidConcurrentModification();
chooseRightIterator();
}
}

Real-World Examples

Text Processing with Iterators

import java.util.*;
public class TextProcessingWithIterators {
// Remove duplicate lines while preserving order
public static List<String> removeDuplicateLines(List<String> lines) {
List<String> result = new ArrayList<>();
Set<String> seen = new HashSet<>();
ListIterator<String> iterator = lines.listIterator();
while (iterator.hasNext()) {
String line = iterator.next();
if (!seen.contains(line)) {
seen.add(line);
result.add(line);
}
}
return result;
}
// Find and highlight text occurrences
public static List<String> highlightText(List<String> lines, String searchText) {
List<String> result = new ArrayList<>();
ListIterator<String> iterator = lines.listIterator();
while (iterator.hasNext()) {
String line = iterator.next();
if (line.contains(searchText)) {
String highlighted = line.replace(searchText, 
"**" + searchText + "**");
iterator.set(highlighted); // Replace in original list
}
result.add(line);
}
return result;
}
// Merge two documents line by line
public static List<String> mergeDocuments(List<String> doc1, List<String> doc2) {
List<String> result = new ArrayList<>();
ListIterator<String> iter1 = doc1.listIterator();
ListIterator<String> iter2 = doc2.listIterator();
while (iter1.hasNext() || iter2.hasNext()) {
if (iter1.hasNext()) {
result.add(iter1.next());
}
if (iter2.hasNext()) {
result.add(iter2.next());
}
}
return result;
}
public static void main(String[] args) {
List<String> document = Arrays.asList(
"Hello world",
"This is a test",
"Hello world", // duplicate
"Another line",
"This is a test" // duplicate
);
System.out.println("Original document: " + document);
// Remove duplicates
List<String> uniqueLines = removeDuplicateLines(document);
System.out.println("After removing duplicates: " + uniqueLines);
// Highlight text
List<String> highlighted = highlightText(new ArrayList<>(document), "test");
System.out.println("After highlighting 'test': " + highlighted);
// Merge documents
List<String> doc1 = Arrays.asList("Line 1", "Line 2", "Line 3");
List<String> doc2 = Arrays.asList("Doc2 Line 1", "Doc2 Line 2");
List<String> merged = mergeDocuments(doc1, doc2);
System.out.println("Merged documents: " + merged);
}
}

Database Result Processing

import java.util.*;
class DatabaseRecord {
private final int id;
private final String name;
private final double value;
private boolean processed = false;
public DatabaseRecord(int id, String name, double value) {
this.id = id;
this.name = name;
this.value = value;
}
public int getId() { return id; }
public String getName() { return name; }
public double getValue() { return value; }
public boolean isProcessed() { return processed; }
public void markProcessed() { this.processed = true; }
@Override
public String toString() {
return String.format("Record{id=%d, name='%s', value=%.2f, processed=%s}", 
id, name, value, processed);
}
}
public class DatabaseResultProcessing {
// Process records in batches
public static void processInBatches(List<DatabaseRecord> records, int batchSize) {
ListIterator<DatabaseRecord> iterator = records.listIterator();
int batchCount = 0;
while (iterator.hasNext()) {
System.out.println("Processing batch " + (++batchCount));
for (int i = 0; i < batchSize && iterator.hasNext(); i++) {
DatabaseRecord record = iterator.next();
processRecord(record);
iterator.set(record); // Update the record
}
// Can go back to review previous records if needed
if (iterator.hasPrevious()) {
DatabaseRecord previous = iterator.previous();
System.out.println("Last processed in batch: " + previous);
iterator.next(); // Move forward again
}
}
}
// Filter and transform records
public static List<DatabaseRecord> filterAndTransform(List<DatabaseRecord> records) {
List<DatabaseRecord> result = new ArrayList<>();
ListIterator<DatabaseRecord> iterator = records.listIterator();
while (iterator.hasNext()) {
DatabaseRecord record = iterator.next();
if (record.getValue() > 50.0) { // Filter condition
DatabaseRecord transformed = transformRecord(record);
result.add(transformed);
// Mark original as processed
record.markProcessed();
iterator.set(record);
}
}
return result;
}
// Find records needing reprocessing
public static List<DatabaseRecord> findRecordsNeedingReprocessing(List<DatabaseRecord> records) {
List<DatabaseRecord> needingReprocessing = new ArrayList<>();
Iterator<DatabaseRecord> iterator = records.iterator();
while (iterator.hasNext()) {
DatabaseRecord record = iterator.next();
if (!record.isProcessed() || record.getValue() < 0) {
needingReprocessing.add(record);
}
}
return needingReprocessing;
}
private static void processRecord(DatabaseRecord record) {
// Simulate processing
record.markProcessed();
System.out.println("Processed: " + record.getName());
}
private static DatabaseRecord transformRecord(DatabaseRecord record) {
// Simulate transformation
return new DatabaseRecord(
record.getId(),
record.getName().toUpperCase(),
record.getValue() * 1.1
);
}
public static void main(String[] args) {
List<DatabaseRecord> records = Arrays.asList(
new DatabaseRecord(1, "Record A", 25.0),
new DatabaseRecord(2, "Record B", 75.0),
new DatabaseRecord(3, "Record C", 150.0),
new DatabaseRecord(4, "Record D", 30.0),
new DatabaseRecord(5, "Record E", 200.0)
);
System.out.println("=== Database Record Processing ===");
// Process in batches
System.out.println("\n1. Processing in batches:");
processInBatches(new ArrayList<>(records), 2);
// Filter and transform
System.out.println("\n2. Filtering and transforming:");
List<DatabaseRecord> filtered = filterAndTransform(new ArrayList<>(records));
System.out.println("Filtered records: " + filtered);
// Find records needing reprocessing
System.out.println("\n3. Finding records needing reprocessing:");
List<DatabaseRecord> needingReprocessing = findRecordsNeedingReprocessing(records);
System.out.println("Needing reprocessing: " + needingReprocessing);
}
}

Summary

Key Takeaways:

  1. Iterator provides forward-only traversal with remove capability
  2. ListIterator extends Iterator with bidirectional traversal and additional operations
  3. Fail-Fast iterators throw ConcurrentModificationException on structural changes
  4. Fail-Safe iterators work on collection copies and don't throw exceptions
  5. Best Practices:
  • Always use hasNext() before next()
  • Use iterator's remove() method for safe deletion
  • Choose the right iterator for your needs
  • Avoid concurrent modifications

When to Use:

  • Iterator: Simple forward traversal, removal needed
  • ListIterator: Bidirectional traversal, modification during iteration
  • for-each: Simple read-only traversal

Iterators are fundamental to Java collections and provide a robust, standardized way to traverse and manipulate collections safely.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper