Explain Codes LogoExplain Codes Logo

What is the difference between Iterator and Iterable and how to use them?

java
iterator-pattern
iterable-implementation
java-best-practices
Nikita BarsukovbyNikita Barsukov·Dec 15, 2024
TLDR

Iterable is an interface that bestows the gift of the "for-each loop" upon an object. By calling iterator(), the Iterable conjures an Iterator for you, equipped with navigation methods like hasNext() and next(), and remove() for modifying the collection like a wizard.

Iterable<Integer> nums = Arrays.asList(1, 2, 3); nums.forEach(System.out::println); // "for who? for-each!" loop Iterator<Integer> it = nums.iterator(); while(it.hasNext()) { System.out.println(it.next()); // Behind the iterator curtain }

Essential definitions and distinction

Before we dive into any more wizardry, let's define our key players:

  • Iterable: The object you can summon an Iterator from. It represents a series of elements you can... well, iterate over.
  • Iterator: The magical tool that iterates. More than a compass, it's a magic carpet that can traverse through the entire structure one next() stop at a time.

The magic of custom Iterable structures

When you craft a custom collection giving it powers of the Iterable, you create a magical gateway to Iterator creation. Such a collection gains the superpower of enhanced for-loop capabilities.

class MyCollection<T> implements Iterable<T> { // A statistician's dream, a data scientist's reality public Iterator<T> iterator() { return new Iterator<T>() { // Like a wizard defining a new spell }; } }

Conquering concurrency

Iterator makes its own path, it doesn't care about others and maintains its own navigation state. This way, multiple Iterators can glide through the same Iterable with no interference. Such freedom!

Iterator<Integer> it1 = nums.iterator(); Iterator<Integer> it2 = nums.iterator(); // They might be twins, but they don't share clothes

Advanced control during iteration

For situations demanding tactical control over the collection during iteration, Iterator is your tactical swiss knife. It can insert, remove, or even modify collection elements while you iterate.

The Iterator's bag of tricks

With great power comes great responsibility and Iterator knows it. Iterators aren't just about walking the walk, they pull out some neat tricks.

The disappearance act: remove()

remove(): a method that asks the troublesome element to "kindly see itself out". Safely deletes the current element during iteration, avoiding potential ConcurrentModificationExceptions.

The silver arrow: Java 8 enhancements

With Java 8 in the quiver, the Iterable interface gets even stronger. It inherited the forEach() method for swift iteration using lambda expressions or method references. This made iterable structures agile at combat against any ambitious collection of data.

The cautionary tale: UnsupportedOperationException

Fear not, brave adventurer! It is still important to note, not every Iterator is equipped with the remove() power. If it isn't, it might boris-johnson-ly stumble over the UnsupportedOperationException.

Best practices for Jedi level Java

Pick Iterable for readability

The for-each loop is good, the ArrayList is great, together they’re a forEach loop that shines brigther than the Death Star!

When to pick Iterator

Try to modify a collection in the middle of an iteration using anything but an Iterator - you’ll feel like stormtroopers are shooting ConcurrentModificationExceptions at you. Use Iterator and may the force be with you!

Evolve, iterate, repeat

The for-loop with an explicit index used to be popular, but it's the same as insisting that the Original Trilogy is the only Trilogy. The Iterable and Iterator allow for modern, evolved, and greater Javaness.