Java | Implementing Iterator and Iterable Interface
Last Updated :
17 Jul, 2018
Iterators are used in Collection framework in Java to retrieve elements one by one. For more details and introduction related to this, see this
link.
Why it is needed to implement Iterable interface?
Every class that implements Iterable interface appropriately, can be used in the enhanced For loop (for-each loop). The need to implement the Iterator interface arises while designing custom data structures.
Example:
for(Item item: customDataStructure) {
// do stuff
}
How to implement Iterable interface?
To implement an iterable data structure, we need to:
- Implement Iterable interface along with its methods in the said Data Structure
- Create an Iterator class which implements Iterator interface and corresponding methods.
We can generalize the pseudo code as follows:
Java
class CustomDataStructure implements Iterable<> {
// code for data structure
public Iterator<> iterator() {
return new CustomIterator<>(this);
}
}
class CustomIterator<> implements Iterator<> {
// constructor
CustomIterator<>(CustomDataStructure obj) {
// initialize cursor
}
// Checks if the next element exists
public boolean hasNext() {
}
// moves the cursor/iterator to next element
public T next() {
}
// Used to remove an element. Implement only if needed
public void remove() {
// Default throws UnsupportedOperationException.
}
}
Note: The Iterator class can also, be implemented as an inner class of the Data Structure class since it won't be used elsewhere.
- How next() and hasNext() work?
To implement an Iterator, we need a cursor or pointer to keep track of which element we currently are on. Depending on the underlying data structure, we can progress from one element to another. This is done in the next() method which returns the current element and the cursor advances to next element.
Before advancing the pointer, we check whether next element exists. i.e. we can picturize the behind-the-scenes code as follows:
While(iterator.hasNext()) { //if next element exists
next(); // advance the pointer
}
- Initializing the cursor
The cursor initialization completely depends on the data structure. For example, in a linked list we would initialize cursor to the head element. In an array list, we would initialize cursor to the 0th element.
From the point of view of implementation:
- If the Iterator class is implemented as an inner class, we can simply use "this" keyword (e.g. cursor = CustomDataStructure.this.element) to access the desired element
- If the Iterator class is implemented as a separate class, we can pass this object of the data structure to the iterator class constructor as demonstrated in the example below.
Below program illustrates the use of Iterable interface:
Given below is a Custom Linked List which makes use of Generics. The linked list consists of Node objects which contain a Generic data value and pointer to next node. The class provides some standard 'get' methods like getHead() and getTail(), and the necessary Iterator() function, which has to be implemented while implementing Iterable interface.
Then the necessary custom class 'ListIterator' is created, which will implement the Iterator interface, along with it the functionalities of hasNext() and next() are also to be implemented. These two functions form the core of Iterable and Iterator interface.
Java
import java.util.Iterator;
// Custom Linked List class using Generics
class List<T> implements Iterable<T> {
Node<T> head, tail;
// add new Element at tail of the linked list in O(1)
public void add(T data)
{
Node<T> node = new Node<>(data, null);
if (head == null)
tail = head = node;
else {
tail.setNext(node);
tail = node;
}
}
// return Head
public Node<T> getHead()
{
return head;
}
// return Tail
public Node<T> getTail()
{
return tail;
}
// return Iterator instance
public Iterator<T> iterator()
{
return new ListIterator<T>(this);
}
}
class ListIterator<T> implements Iterator<T> {
Node<T> current;
// initialize pointer to head of the list for iteration
public ListIterator(List<T> list)
{
current = list.getHead();
}
// returns false if next element does not exist
public boolean hasNext()
{
return current != null;
}
// return current data and update pointer
public T next()
{
T data = current.getData();
current = current.getNext();
return data;
}
// implement if needed
public void remove()
{
throw new UnsupportedOperationException();
}
}
// Constituent Node of Linked List
class Node<T> {
T data;
Node<T> next;
public Node(T data, Node<T> next)
{
this.data = data;
this.next = next;
}
// Setter getter methods for Data and Next Pointer
public void setData(T data)
{
this.data = data;
}
public void setNext(Node<T> next)
{
this.next = next;
}
public T getData()
{
return data;
}
public Node<T> getNext()
{
return next;
}
}
// Driver class
class Main {
public static void main(String[] args)
{
// Create Linked List
List<String> myList = new List<>();
// Add Elements
myList.add("abc");
myList.add("mno");
myList.add("pqr");
myList.add("xyz");
// Iterate through the list using For Each Loop
for (String string : myList)
System.out.println(string);
}
}
Similar Reads
Iterator Interface In Java Java Iterator Interface of java collections allows us to access elements of the collection and is used to iterate over the elements in the collection(Map, List or Set). It helps to easily retrieve the elements of a collection and perform operations on each element. Iterator is a universal iterator a
6 min read
Iterable Interface in Java The Iterable interface was introduced in JDK 1.5. It belongs to java.lang package. In general, an object Implementing Iterable allows it to be iterated. An iterable interface allows an object to be the target of enhanced for loop(for-each loop). Definition of Iterable public interface Iterable<T
3 min read
Convert Iterator to Iterable in Java Given an Iterator, the task is to convert it into Iterables in Java. Examples: Input: Iterator = {1, 2, 3, 4, 5} Output: {1, 2, 3, 4, 5} Input: Iterator = {'G', 'e', 'e', 'k', 's'} Output: {'G', 'e', 'e', 'k', 's'} Below are the various ways to do so: By overriding the abstract method Iterable.itera
3 min read
IntStream iterator() in Java In Java, streams are used to process sequences of data efficiently. IntStream is a special type of stream which is designed to handle primitive int values. This avoids the need for converting the primitive types into objects.The iterator() method in IntStream is a terminal operation that gives us an
3 min read
Convert an Iterable to Collection in Java Iterable and Collection have served to be of great use in Java. Iterators are used in Collection framework in Java to retrieve elements one by one and a Collection is a group of individual objects represented as a single unit. Java provides Collection Framework which defines several classes and inte
4 min read