-2

By this below definition(pre 1.8) of Iterable,

package java.lang;

import java.util.Iterator;


public interface Iterable<T> {
    Iterator<T> iterator();
}

I would say that, Iterable is dependent on Iterator interface as shown below,

package java.util;

public interface Iterator<E> {

    boolean hasNext();


    E next();


    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

}

Standard recommendation is that, any implementation that implements Iterable interface becomes iterable.

But syntactically, MyClasscan implement interface Iterator and enable the implementation MyClass as iterable without explicitly mentioning class MyClass **implements Iterable**{}, by adding Iterator<T> iterator(); behavior in Iterator interface instead of Iterable interface. This would have simplified presenting only one interface(Iterator). Iterator can hold all the responsibilities that Iterable does.

So, What is the rational behind adding Iterator<T> iterator(); behavior in Iterable(redundant) interface instead of Iterator interface?

I am not clear with the purpose of introducing Iterable interface.

Please help me understand.

For me, this is not a duplicate question because this is an answer which talks about violation of SRP.

overexchange
  • 2,265

1 Answers1

3

Iterator is stateful, Iterable is stateless.

Iterator knows where it is at the moment, but Iterable shouldn't, because it can be iterated by two (or more) independent "actors".

Basically Iterable is able to provide anyone with a brand new Iterator on demand.

It looks like this question keeps on coming up, although mostly on StackOverflow not here:

https://stackoverflow.com/questions/6863182/what-is-the-difference-between-iterator-and-iterable-and-how-to-use-them

https://stackoverflow.com/questions/839178/why-is-javas-iterator-not-an-iterable

  • What is the advantage of introducing Iterable and making it stateless? what is the disadvantage in making iterator() method sit in Iterator interface? As said: Iterable implies that one may obtain an iterator from an object to traverse over its elements, this responsibility can be hold by Iterator – overexchange Jul 23 '15 at 06:55
  • 2
    @overexchange you don't want your iterable MyClass instance to know that it's being iterated by someone right now, and to keep track of it - to know that this someone is on the 5th element at the moment ;) For one, because it would make difficult for someone else to iterate over its elements at the same time. As for squashing Iterable and Iterator into one interface, it would violate Single Responsibility Principle. Being an iterator (keeping track of the act of iterating over elements), and being able to build new iterators are two different responsibilities. – Konrad Morawski Jul 23 '15 at 07:00
  • @overexchange and you wouldn't want your MyClass to be its own iterator, for the reasons explained above - but if Iterable and Iterator were combined in one interface, you could not avoid it. – Konrad Morawski Jul 23 '15 at 07:01
  • to be its own iterator? I would not try mentioning class Myclass implements Iterator{} instead the private inner class would implement Iterator. I agree with your point that single interface violates SRP. – overexchange Jul 23 '15 at 07:06
  • @overexchange ok I see - but if you only had Iterator as an inner class, how would the outer world know that it can iterate over MyClass in a for ... in loop? Making it Iterable says that explicitly and it seems like the cleanest possible way – Konrad Morawski Jul 23 '15 at 07:24
  • Knowing to the outer world is not a severe issue. Because, Does the outer world know that java arrays are Cloneable & Serializable by using some syntax except reading java documentation? you dont have syntactic proof for it, because array types are not visible.I feel SRP is strong reason for this division, and Iterable sits in java.lang and Iterator sits in java.util. – overexchange Jul 23 '15 at 07:28
  • @overexchange correct, but Serializable does nothing, it's a marker interface. Iterable is more like Parcelable in that you're actually supposed to flesh some implementation out. You can delegate iteration to a child class (eg. a collection you enwrap) just by returning its iterator as your own. And if Java ever got reified generics (like C#), MyClass could simultaneously support Iterable<Integer> and Iterable<String>, and you could iterate it as an integer or string sequence alike. Thanks for accepting my answer – Konrad Morawski Jul 23 '15 at 07:50