Implementing Iterable interface in Java to enable
for-each loop based iteration
how to implement java.lang.Iterable<T> on a class to enable for-each loop based iteration
through the collection of objects stored in that class. Tutorial starts off
with explaining how Iterable and for-each loop are related, then explains how to
implement Iterable<T>, and finally shows a Java code example showing Iterable interface implementation and implementing class’ use in a for-each
loop.
Iterable<T> and the for-each
loop
Java 5 introduced for-each loop which took away the error-prone aspect of looping, specifically the need to manage loop-counter variable and end-of-loop conditions. All one now needs to do to iterate over a collection using the for-each loop is to write something like this –
Java 5 introduced for-each loop which took away the error-prone aspect of looping, specifically the need to manage loop-counter variable and end-of-loop conditions. All one now needs to do to iterate over a collection using the for-each loop is to write something like this –
Typical for-each construct usage
for(MyClass
myClassObject: list){
//code
to use myClassObject
}
|
Where list is an instance of java.util.List<MyClass>.
Most of the important in-built
collection types now support iteration using the enhanced for-each loop.
This is by virtue of their implementing the interface Iterable<T>.
In fact, any class which implements Iterable<T>, can be used in a for-each loop to iterate over the objects
of type T which it holds or encapsulates. Extending this logic to the
small code snippet we saw above – MyCollection which
implements Iterable<MyClass>, can be used in a for-each loop to iterate through MyClass objects stored in it.
Having understood the relationship
between implementing Iterable interface and use of the implementing class in for-each
loop, let us now understand how to go about implementing Iterable.
How to implement Iterable<T>
interface
Any class implementing Iterable<T> needs to follow three simple steps –
Any class implementing Iterable<T> needs to follow three simple steps –
- Implement Iterable<T> interface.
- Override Iterable’s iterator() method.
- Return an instance of Iterator<T> from the iterator() method.
So, if you have an API/Class
containing a collection of String type of elements, and you want clients of this API to be
able to access theString objects using a for-each loop, then your three steps of
implementing Iterable<String> would go like this –
- Implement Iterable<String>.
- Override Iterable’s iterator() method.
- Return an instance of Iterator<String> from the iterator() method.
Simple, right! There is a small
piece of logic missing though!!How do you get hold of an Iterator<String> instance pointing to your stored collection?
The general practice in this
case is to return the in-built Iterator instance of the collection class you use to store the iterable
objects in your API. So, if you use a List<String>
to store the String objects to be iterated, then you return Iterator<String> returned by List.iterator()
method as the output of overridden Iterable.iterator()
method.
Let us see a Java code example to
see how Iterable<T> implementation can be done.
Java code example showing Iterable<T>
implementation
Lets take a simple case of aggregation to show an Iterable<T> implementation in action. For our example scenario we have 2 types – Department and Employee. A Department instance holds multiple Employee instances in a employee list, or List<Employee>.
Lets take a simple case of aggregation to show an Iterable<T> implementation in action. For our example scenario we have 2 types – Department and Employee. A Department instance holds multiple Employee instances in a employee list, or List<Employee>.
We will make Department class implement the Iterable<Employee>
interface. Doing so would would allow us to iterate through employees of a
department using the for-each loop just by getting hold of a Department instance. Let us see the code in action now, which will be
followed by detailed explanation of the code.
Java code example showing Iterable implementation
//Employee.java(POJO)
package com.javabrahman.corejava;
public class Employee
{
private String
name;
private Integer
age;
public Employee(String
name, Integer age) {
this.name
= name;
this.age
= age;
}
//setters
and getters for name & age go here
//standard
override of equals() & hashcode() methods goes here
}
//IterableDepartment.java
which implements Iterable<Employee>
package com.javabrahman.corejava;
import java.util.List;
import java.util.Iterator;
public class IterableDepartment
implements Iterable<Employee> {
List<Employee>
employeeList;
public IterableDepartment(List<Employee>
employeeList){
this.employeeList=employeeList;
}
@Override
public Iterator<Employee>
iterator() {
return employeeList.iterator();
}
}
//Client class
IterableDeptClient.java
//Iterates through
IterableDepartment's employees using for-each loop
package com.javabrahman.corejava;
import java.util.Arrays;
import java.util.List;
public class IterableDeptClient
{
public static void main(String
args[]){
List<Employee>
employeeList
=
Arrays.asList(new Employee("Tom Jones", 45),
new Employee("Harry
Jones", 42),
new Employee("Ethan
Hardy", 65),
new Employee("Nancy
Smith", 22),
new Employee("Deborah
Sprightly", 29));
IterableDepartment
iterableDepartment=new IterableDepartment(employeeList);
for(Employee
emp: iterableDepartment){
System.out.println(emp.getName());
}
}
}
|
OUTPUT of the above code
Tom Jones
Harry Jones
Ethan Hardy
Nancy Smith
Deborah Spright
Explanation of the code
- Employee.java is the POJO class in this example. It has only 2 attributes name & age.
- IterableDepartment class contains a List attribute named employeeList which is initialized using IterableDepartment’s only public constructor.
- IterableDeptClient first creates an employee list consisting of 5 employees, and then passes this employee list to the constructor of the new IterableDepartment instance it creates.
- Then it iterates through the Employee objects in the IterableDepartment instance using a for-each loop.
- In each iteration of the for-each loop, name of the employee encountered is printed. As expected, the for-each loop correctly iterates through the 5 Employee objects stored in the IterableDepartment instance, and prints their names.
Summary
In the above tutorial we understood how Iterable interface can be implemented on a class holding a collection of objects. We then saw with a Java code example showing how such a collection can be iterated through using the enhanced for-each loop.
In the above tutorial we understood how Iterable interface can be implemented on a class holding a collection of objects. We then saw with a Java code example showing how such a collection can be iterated through using the enhanced for-each loop.
No comments:
Post a Comment