-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,245
  • 2
  • 17
  • 47
  • 2
    possible duplicate of [Is there a difference between iterable and enumerable?](http://programmers.stackexchange.com/questions/216988/is-there-a-difference-between-iterable-and-enumerable) – Konrad Morawski Jul 23 '15 at 06:48
  • For me, this is not duplicate question, below answer gives exact reason: *Being an iterator (keeping track of the act of iterating over elements), and being able to build new iterators are two different responsibilities* as mentioned below. None of the previous questions answered this exact reason. – overexchange Jul 23 '15 at 07:10
  • @KonradMorawski one can argue that question boils down to matters of [tag:single-responsibility] and as such, is also a duplicate of [What is the real responsibility of a class?](http://programmers.stackexchange.com/q/220230/31260) :) – gnat Jul 23 '15 at 12:44
  • @gnat i might have pasted a wrong link, i can't remember. anyway, this question is actually much more similar to 2 questions posted on StackOverflow - see the links in my answer. but since SO is technically another site, the input form wouldn't let me submit a link to neither of them – Konrad Morawski Jul 23 '15 at 12:48

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

Konrad Morawski
  • 9,721
  • 4
  • 37
  • 58
  • 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` and `Iterable`, 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