Iterable vs Iterator in Java

Chunks
2 min readMay 13, 2021

--

Iterable and Iterator are both interfaces in Java that sound alike and are often confusing to Java developers. Let’s start by defining the word “iteration”.

From Merriam-Webster dictionary, an iteration is the repetition of a sequence of computer instructions a specified number of times or until a condition is met.

Basically, you can liken an iteration to looping, where you go or run through a list of items e.g for-each loop

In java, if a class implements Iterable interface, that class gains the ability to be iterated/looped over using an iterator like for-each loop. This is done by calling the iterator() method that must be implemented by the class that implements Iterable.

For example, List interface extends Collection interface, while the Collection interface extends Iterable interface which makes it possible for a List to be iterated using for-each loop.

List<Integer> integers = new ArrayList<>(Arrays.asList(1, 2, 3));

for (Integer number : integers) {
System.out.println(number);
}

Iterator on the other hand, manages the iteration that happens in an Iterable. it has the position or holds the current state of where the iteration is during an iteration or loop. it does this by using some inbuilt helper methods such as hasNext() and next(). An example is shown below:

Iterator<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5).iterator();
while (numbers.hasNext()) {
System.out.println(numbers.next());
}

What is the relationship between Iterable and Iterator ? The relationship between both interfaces is that they work together to iterate or loop through objects in java. In a nutshell, When you implement an Iterable, you are making that “loopable” and an Iterator helps to make it “loopable ”by providing helper methods such as hasNext() and next(). The next section shows how you can combine both Iterable and Iterator.

IMPLEMENTING A CUSTOM ITERABLE AND ITERATOR

In this section, we will create a custom iterable that implements Iterable interface and likewise a custom iterator that implements Iterator interface and finally see how both work together.

public class CustomIterable<T> implements Iterable<T> {
List<T> values = new ArrayList<>();

public void add(T value) {
values.add(value);
}
@Override
public Iterator<T> iterator() {
return new CustomIterator<T>(values);
}

public class CustomIterator<E> implements Iterator<E> {

List<E> data;
int position = 0;

public CustomIterator(List<E> data) {
this.data = data;
}

@Override
public boolean hasNext() {
return data.size() > position + 1;
}

@Override
public E next() {
E nextValue = this.data.get(position);
position++;
return nextValue;
}
}
}

The above code shows how you can customize an iterable. It works just like List in java which is an iterable. The code below shows how you can use CustomIterable class.

public static void main(String[] args) {
CustomIterable<Integer> integers = new CustomIterable<>();
integers.add(1);
integers.add(2);
integers.add(3);
integers.add(4);
integers.add(5);

for (Integer integer : integers)
System.out.println(integer);
}

The above code prints 1,2,3,4,5 using for-each loop which implicitly makes use of an Iterator and its method (hasNext() and next()).

With CustomIterable, you can decide that you do not want next() to return the next element but rather it should return next two elements by just incrementing position by 2 (position += 2).

--

--