Source:
Any object that can be usable to iterate each of its elements using a special kind of loop (usually for with different sense) and without touch its index is an Iterable.
Java
<type> <name> : <iterable>)public class Test {
public static void main(String[] args) {
int[] numbers = { 3, 5, 6, 8, 1 };
for(int number : numbers)
System.out.print(number + " ");
}
}
JavaScript
let|var <name> of <iterable>)<script>
let numbers = [3, 5, 6, 8, 1]
let result = ''
for(number of numbers)
result += number + ' '
canvas.innerHTML = result
</script>
In Java, instance of all classes that implement Iterable<T> interface including array are iterable object. This interface has a single abstract method java.util.Iterator<T> iterator(), will returns an iterator over a set of elements of type T.
foreach starts, it calls iterator method.boolean hasNext(), T next() and void remove() (optional) methods.foreach wants the next value, it calls hasNext() on that object.next() must returns the next element in the iteration, otherwise it will throw java.util.NoSuchElementException.The optional
remove()method removes from the underlying collection the last element returned by this iterator. This method can be called only once per call tonext(). The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.
But JavaScript, arrray, String and all objects that has special built-in Symbol.iterator method are iterable. So,
for .. of starts, it calls the method, or errors if not found.next method.for .. of wants the next value, it calls next() on that object.next() must have the object {done: Boolean, value: <any>}, where done = true means that the iteration is finished, otherwise value must be the new value.Java
java.lang.Iterable<T> interface.Iterator<Integer> iterator(), always return a new iterator object.java.utli.Iterator<T> interface as an iterator object that will be created each of iterator() invocation.import java.util.Iterator;
public class Test {
public static void main(String[] args) {
for(int number : new Trove())
System.out.print(number + " ");
}
public static class Trove implements Iterable<Integer> {
@Override
public Iterator<Integer> iterator() {
return new Treasure(-2, 4);
}
public static class Treasure implements Iterator<Integer> {
private int start, limit, current;
private Treasure(int start, int limit) {
if(start > limit)
throw new UnsupportedOperationException();
this.start = start;
this.limit = limit;
this.current = start;
}
@Override
public boolean hasNext() {
return limit >= current;
}
@Override
public Integer next() {
return current++;
}
}
}
}
JavaScript
Just create an object containing Symbol.iterator and next method.
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<p id='canvas'></p>
<script>
let trove = {
start: 1,
limit: 7,
[Symbol.iterator]() {
this.current = this.start;
return this;
},
next() {
if(this.limit >= this.current)
return { done: false, value: this.current++ }
else
return { done: true }
}
}
let result = '';
for(e of trove)
result += e + ' '
canvas.innerHTML = result
</script>
</body>
</html>
There are two official terms that look similar in JavaScript, but are very different. Please make sure you understand them well to avoid the confusion.
- Iterables are objects that implement the
Symbol.iteratormethod, as described above.- Array-likes are objects that have indexes and length, so they look like arrays.
But an iterable may be not array-like. And vice versa an array-like may be not iterable.
To make both iterable and array-like a real array, there’s a built-in method Array.from that transforms them to the real one.