1
public interface Walkable {
    void walk();
}

class Animal implements Walkable{
    public void walk() {
        //defines some way to walk
    }
}

In the above example, the Animal class says that it can walk and it has defined how it is walking.

Similarly why cant any aggregation of objects just implement Iterator interface and imply that it is Iterable.

class Employee{
    Iterator getEmployeeIterator(){
        return new EmployeeCollection();
    }
}

class EmployeeCollection implements Iterator{
    Employee []emp;
    public boolean hasNext() {
        //implementation
    }
    public Object next() {
        //implementation
    }

What is the need of the Iterable interface which simply returns the Iterator? It does not take any argument also. If it takes any arguments, I can assume it can work like a factory providing different types of Iterators

Is "providing a common interface" is the sole purpose of Iterable?

justinhj
  • 11,147
  • 11
  • 58
  • 104
James
  • 161
  • 1
  • 6
  • 3
    No. Enhanced for loops can use Iterables. – Johannes Kuhn Apr 17 '20 at 19:51
  • http://tutorials.jenkov.com/java-collections/iterable.html See this page. Johannes is right, if your class implements Iterable, you can use it in for loops directly. – Tom Cools Apr 17 '20 at 19:54
  • does this answer your question? https://stackoverflow.com/questions/6863182/what-is-the-difference-between-iterator-and-iterable-and-how-to-use-them – Joni Apr 17 '20 at 19:59
  • @Joni, not exactly. – James Apr 17 '20 at 20:02
  • I would say yes. That's the purpose of all interfaces, to 'provide a common interface'; in this case it's the common interface that enhanced loops know how to handle different (un-related) data. It's the difference between `for (Employee e : empCollection.getEmployeeIterator())` and `for(Employee e: empCollection)` which one looks better? – kendavidson Apr 17 '20 at 20:08
  • The Iterable is defined as a generic type. ` Iterable` , where T type parameter represents the type of elements returned by the iterator. – Kaumadie Kariyawasam Mar 19 '21 at 08:41

2 Answers2

3

why cant any aggreagtion of objects just implement Iterator interface and imply that it is Iterable

An iterator has state. It has to know what items the iterator has already returned, which items have not, and which item will be returned next.

If a collection was iterator itself, and the enhanced for loop worked on iterators, you would not be able iterate on it twice like this:

for (Employee employee: employeeCollection) {
    // do something
}
for (Employee employee: employeeCollection) {
    // do something else
}

When the first loop completes, that means you have reached the end of the iteration. Therefore the second loop can not iterate on any more items.

You could argue that the start of the loop could somehow implicitly "reset" the iterator back to the start. There is no way to reset an iterator, but that wouldn't solve the problem anyway. How would nested iteration work, let's say you are looking for pair of employees that have the same birthday?

for (Employee employee1: employeeCollection) {
    for (Employee employee2: employeeCollection) {
        // do something
    }
}

If the inner for-loop and outer for-loop share the iterator state, there is no way this algorithm can produce all pairs of employees.

You really need there to be a way to create a fresh iterator that's indepedent of other iterators that may exist. That is what the Iterable interface gives you.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • 1
    Further, two threads can iterate over the same collection without additional measures, because iteration is considered a read-only operation, which doesn’t alter the shared state. This implies that each thread must have its own local `Iterator` instance. It would also spoil the concept of immutable collections, if they had to maintain mutable state for iterations. – Holger Apr 28 '20 at 11:33
2

I could think of one reason also pointed out in the commentss. First of all, if you implement Iterable and override the forEach() method, then you can iterate through data structures like this:

for(int i : myDataStructure) {
    System.out.println(i);
}

If implemented correctly, it should print all the elements in your data structure. For each loops are easier than regular for loops in the sense that different data structures have different ways of iterating. For example with LinkedList if you use a for loop to iterate it will take a longer time since you always start from the head and go to the node at that index every single time. With for-each loops, it saves space and time depending on the data structure.

Higigig
  • 1,175
  • 1
  • 13
  • 25