Week 51 — What is `Iterable` and how does it relate to for-each/enhanced `for` loops?

Question of the Week #51
What is Iterable and how does it relate to for-each/enhanced for loops?
8 Replies
Eric McIntyre
Eric McIntyre12mo ago
Iterable is an interface for objects that can be iterated over. It contains a single method named iterator which should return an Iterator object. This object allows to navigate through the Iterable and access its elements. It has a hasNext method which checks whether further elements are available and a next method which gets the current element and moves to the next. As an example, the following Range record implements Iterable to iterate over Integers starting from a specific element until a specific element with a given step size.
public record Range(int start, int end, int stepSize) implements Iterable<Integer>{
public Range{
//vaidation in constructor
if(end <= start) {
throw new IllegalArgumentException("end must be after start");
}

if(stepSize <= 0) {
throw new IllegalArgumentException("stepSize must be strictly positive");
}
}
@Override
public Iterator<Integer> iterator(){
return new Iterator<>(){
private int current = start;
@Override
public boolean hasNext(){
//checks whether an element is available
return current < end;
}
@Override
public Integer next(){
if(!hasNext()){
//throw an exception if no element is available
throw new NoSuchElementException("next() called but no next element available");
}
//return the current element and move to the next
Integer ret = current;
current += stepSize;
return ret;
}
};
}
}
public record Range(int start, int end, int stepSize) implements Iterable<Integer>{
public Range{
//vaidation in constructor
if(end <= start) {
throw new IllegalArgumentException("end must be after start");
}

if(stepSize <= 0) {
throw new IllegalArgumentException("stepSize must be strictly positive");
}
}
@Override
public Iterator<Integer> iterator(){
return new Iterator<>(){
private int current = start;
@Override
public boolean hasNext(){
//checks whether an element is available
return current < end;
}
@Override
public Integer next(){
if(!hasNext()){
//throw an exception if no element is available
throw new NoSuchElementException("next() called but no next element available");
}
//return the current element and move to the next
Integer ret = current;
current += stepSize;
return ret;
}
};
}
}
Eric McIntyre
Eric McIntyre12mo ago
Once we have an Iterable object, an enhanced for loop can be used to iterate over it.
for(Integer i:new Range(0,10,2)){
System.out.println(i);
}
for(Integer i:new Range(0,10,2)){
System.out.println(i);
}
This is equivalent to the following code:
Range range = new Range(0,10,2);
for(Iterator<Integer> it = range.iterator(); it.hasNext();){
Integer i = it.next();
System.out.println(i);
}
Range range = new Range(0,10,2);
for(Iterator<Integer> it = range.iterator(); it.hasNext();){
Integer i = it.next();
System.out.println(i);
}
📖 Sample answer from dan1st
Eric McIntyre
Eric McIntyre12mo ago
It is an interface, that allows you to call the forEach method on the collection of data you are making. Example would be an Inventory class that takes a collection of Products.
Submission from smokeintitan
Eric McIntyre
Eric McIntyre12mo ago
it is an interface which Collection also implement and
for(T t : this) {
// iterables

}
for(T t : this) {
// iterables

}
Eric McIntyre
Eric McIntyre12mo ago
this how forEach is implemented
Submission from kokoko2023
Eric McIntyre
Eric McIntyre12mo ago
Doesn't it allow objects to be the target of enhanced for-each/enhanced loops.
Submission from PNJ3.0#1519
Eric McIntyre
Eric McIntyre12mo ago
Iterable is the posibility of iterating variable like integer ,double which well achieved during loops like for each and enhanced for loops Here is code snippet: int[] goals={2,4,5,8,1,0}; for(int position:goals){ System.out.println(position); } //the end.
Submission from trailblazer_g
Eric McIntyre
Eric McIntyre12mo ago
Iterable is an interface implemented for types with the ability to iterate. When a class implements the Iterable Interface they are now forced to abide by the contract by implementing the iterator method. This method returns an iterator that can be used to iterate over the object based on the contract of the interface. After implementing the iterator method, an Object of that type can now be iterated over by a for-each loop. Other than allowing for the new syntax, the Iterable interface also gives access to two other default methods: the forEach method, providing an even more concise solution when paired with method reference; the spliterator, an iterator with splitting capability suitable for parallelism.
// here is an example.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

record Dog(String name, int age, String breed) {
public void speak() {
System.out.println("roof! roof! my name is " + name + " roof! roof!");
}
}

class DogPark implements Iterable<Dog> {
private Iterator<Dog> dogIterator;

public DogPark(Dog... dogs) {

dogIterator = List.of(dogs).iterator();

}

@Override
public Iterator<Dog> iterator() {
return dogIterator;
}
}

public class Main {

public static void main(String[] args) {

Dog[] dogs = {
new Dog("Buddy", 5, "Beagle"),
new Dog("Charlie", 10, "Australian Shepherd"),
new Dog("Max", 12, "Jack Russell Terrier"),
};

var dogPark = new DogPark(dogs);

for (Dog dog : dogPark) {
dog.speak();
}

dogPark.forEach(Dog::speak);

// both previous statements function the same yet the latter is less verbose.

}
}
// here is an example.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

record Dog(String name, int age, String breed) {
public void speak() {
System.out.println("roof! roof! my name is " + name + " roof! roof!");
}
}

class DogPark implements Iterable<Dog> {
private Iterator<Dog> dogIterator;

public DogPark(Dog... dogs) {

dogIterator = List.of(dogs).iterator();

}

@Override
public Iterator<Dog> iterator() {
return dogIterator;
}
}

public class Main {

public static void main(String[] args) {

Dog[] dogs = {
new Dog("Buddy", 5, "Beagle"),
new Dog("Charlie", 10, "Australian Shepherd"),
new Dog("Max", 12, "Jack Russell Terrier"),
};

var dogPark = new DogPark(dogs);

for (Dog dog : dogPark) {
dog.speak();
}

dogPark.forEach(Dog::speak);

// both previous statements function the same yet the latter is less verbose.

}
}
⭐ Submission from karter907
Want results from more Discord servers?
Add your server