java - What is the difference between iterator and iterable and how to use them? - Stack Overflow
Convert Java Array to Iterable - Stack Overflow
When should I accept a parameter of Iterable<T> vs. Collection<T> in Java? - Stack Overflow
java - Iterable as a return type - Stack Overflow
I just had to implement this to iterate through some private data structure. What threw me off is I couldn't index or do checks like I would with an array or list. I understand in general it is exactly like it sounds- used to iterate over some collection. Also that it is something we take for granted such as when using a foreach. That is all I get about it, it just seems like an inconvenience right now...
An Iterable is a simple representation of a series of elements that can be iterated over. It does not have any iteration state such as a "current element". Instead, it has one method that produces an Iterator.
An Iterator is the object with iteration state. It lets you check if it has more elements using hasNext() and move to the next element (if any) using next().
Typically, an Iterable should be able to produce any number of valid Iterators.
An implementation of Iterable is one that provides an Iterator of itself:
public interface Iterable<T>
{
Iterator<T> iterator();
}
An iterator is a simple way of allowing some to loop through a collection of data without assignment privileges (though with ability to remove).
public interface Iterator<E>
{
boolean hasNext();
E next();
void remove();
}
See Javadoc.
Integer foo[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
List<Integer> list = Arrays.asList(foo);
// or
Iterable<Integer> iterable = Arrays.asList(foo);
Though you need to use an Integer array (not an int array) for this to work.
For primitives, you can use guava:
Iterable<Integer> fooBar = Ints.asList(foo);
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
<type>jar</type>
</dependency>
For Java8 with lambdas: (Inspired by Jin Kwon's answer)
final int[] arr = { 1, 2, 3 };
final Iterable<Integer> i1 = () -> Arrays.stream(arr).iterator();
final Iterable<Integer> i2 = () -> IntStream.of(arr).iterator();
final Iterable<Integer> i3 = () -> IntStream.of(arr).boxed().iterator();
just my 2 cents:
final int a[] = {1,2,3};
java.lang.Iterable<Integer> aIterable=new Iterable<Integer>() {
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private int pos=0;
public boolean hasNext() {
return a.length>pos;
}
public Integer next() {
return a[pos++];
}
public void remove() {
throw new UnsupportedOperationException("Cannot remove an element of an array.");
}
};
}
};
Many of the collection types existed before Iterable<T> (which was only introduced in 1.5) - there was little reason to add a constructor to accept Iterable<T> as well as Collection<T> but changing the existing constructor would have been a breaking change.
Personally I would use Iterable<T> if that allows you to do everything you want it to. It's more flexible for callers, and in particular it lets you do relatively easy filtering/projection/etc using the Google Java Collections (and no doubt similar libraries).
An Iterable produces Iterator objects. An Iterator object, by definition, iterates. Notice, that the Iterator interface makes no promise as to how many times next() can be called before hasNext() returns false. An Iterator could possibly iterate over Integer.MAX_VALUE + 1 values before its hasNext() method returns false.
However, a Collection is a special form of Iterable. Because a Collection cannot have more than Integer.MAX_VALUE elements (by virtue of the size() method), it is naturally presumed that its Iterator objects will not iterate over this many elements.
Therefore, by accepting a Collection rather than an Iterable, your class can have some guarantee over how many elements are being passed in. This is especially desirable if your class is itself a Collection.
Just my two cents...
It looks like your class should have an implementation of Iterable<ClientInterface> as a class member, like ArrayList.
Let's use this as an example:
public class Bus {
private ArrayList<Person> riders;
... //constructors and other methods
public Iterable<Person> getRiders() {
return riders;
}
... //other methods
}
Everything can be a return type: an enum, a class, an interface, an int, an exception etc.
Iterable is an interface which could be used to use the return in a foreach call (that's why you can use for(T something : AnArrayList) because ArrayList<T> implements Iterable<T>)
Now, my answer contains an example:
We have a method getNeighbours which returns Iterable<ClientInterface>
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>();
}
Well, ok since Iterable is just an interface we need to implement methods or use an implementation.
Since it's something which we should do manually we should implement the methods by ourself.
The only method (in Java8, there are 3 methods but we will ignore it) is iterator() which returns an iterator.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
@Override
public Iterator<ClientInterface> iterator()
{
return null;
}
};
}
Iterator is another interface which is used to provide the logic to iterate over the collection, a list of items etc.
We are forced to implements two methods: hasNext and next
hasNext is used to determinate if there are more items to iterate over, next is used to iterate over it.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
@Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
@Override
public boolean hasNext()
{
return false;
}
@Override
public ClientInterface next()
{
return null;
}
};
}
};
}
We here need to remember which was our last position so we would create a field inside our Iterator.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
@Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
private int position;
@Override
public boolean hasNext()
{
return false;
}
@Override
public ClientInterface next()
{
return null;
}
};
}
};
}
Here the problem: What we should iterate? It depends to you, an example could be:
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
@Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
private int position;
private ClientInterface[] items = new ClientInterface[]{new ClientInterface(), new ClientInterface()};
@Override
public boolean hasNext()
{
return position != items.length;
}
@Override
public ClientInterface next()
{
if (!hasNext()) throw new NoSuchElementException();
return items[position++];
}
};
}
};
}
Note here how we created an array of items and used our two methods hasNext and next to provide a way to iterate over it.
Every call of next increment the internal pointer, and our hasNext method just checks if the pointer reached the end of the array.
Collections like ArrayList, LinkedList etc. already did the job for you and better (implements remove method) you can get this iterator by using ArrayList.iterator()
Now you could write something like:
for (ClientInterface el : yourClass.getNeighbours())
{
System.out.println(el);
}
Although there is no class that would immediately suit your needs and be intuitive to the readers of your test code, you can easily create your own anonymous class that is easy to understand:
static Iterable<Integer> range(final int from, final int to) {
return new Iterable<Integer>() {
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int current = from;
public boolean hasNext() { return current < to; }
public Integer next() {
if (!hasNext()) { throw new NoSuchElementException(); }
return current++;
}
public void remove() { /*Optional; not implemented.*/ }
};
}
};
}
Demo.
This implementation is anonymous, and it does not implement Collection<Integer>. On the other hand, it produces a non-empty enumerable sequence of integers, which you can fully control.
To answer the question as per title:
Are there any Java standard classes that implement
Iterablewithout implementingCollection?
From text:
If there ever are any classes that can implement
Iterable<T>that don't also implementCollection<T>?
Answer:
Yes
See the following javadoc page: https://docs.oracle.com/javase/8/docs/api/java/lang/class-use/Iterable.html
Any section that says Classes in XXX that implement Iterable, will list Java standard classes implementing the interface. Many of those don't implement Collection.