🌐
Jenkov
jenkov.com › tutorials › java-collections › iterable.html
Java Iterable
May 25, 2020 - The second way you can iterate the elements of a Java Iterable is by obtaining a Java Iterator from it by calling the Iterable iterator() method. You can then iterate through that Iterator like you would with any other Iterator. You can read more about the Java Iterator in my Java Iterator tutorial . Here is an example of iterating the elements of a Java Iterable (a Java List in this example):
🌐
GeeksforGeeks
geeksforgeeks.org › java › iterable-interface-in-java
Iterable Interface in Java - GeeksforGeeks
March 31, 2026 - We can iterate the elements of Java Iterable by obtaining the Iterator from it using the iterator() method.
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › lang › Iterable.html
Iterable (Java Platform SE 8 )
July 21, 2026 - Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified).
🌐
Scaler
scaler.com › home › topics › java › iterable interface in java
Iterable Interface in Java - Scaler Topics
April 27, 2024 - The Iterable interface is present in java.lang.Iterable package. Learn detailed explanation and implementation with an example of Iterable and Iterator Interfaces on Scaler Topics.
🌐
iO Flood
ioflood.com › blog › java-iterable
Java Iterable Interface: Guide and Examples
February 20, 2024 - In this example, we’ve created a class MyIterable that implements the Iterable interface. We then create an instance of MyIterable and use a for-each loop to iterate over each element, printing each string to the console. This is just a basic way to use the Iterable interface in Java, but there’s much more to learn about it.
🌐
Baeldung
baeldung.com › home › java › java collections › differences between iterator and iterable and how to use them?
Differences Between Iterator and Iterable and How to Use Them? | Baeldung
June 27, 2025 - All collections in Java implement the Iterable interface. We can iterate over elements inside a collection using the enhanced for loop, also called the for-each loop. However, only objects that implement an Iterable interface can be used within such a statement. It’s also possible to iterate over elements using the while statement in combination with an Iterator. Let’s see an example of iterating over elements in a List using the for-each statement:
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › lang › Iterable.html
Iterable (Java SE 17 & JDK 17)
April 21, 2026 - Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Actions are performed in the order of iteration, if that order is specified.
🌐
Java Code Geeks
examples.javacodegeeks.com › home › java development › core java › util › iterator
Iterable Java Example - Examples Java Code Geeks - 2026
August 10, 2020 - The example has the iterable implementation MyIterable.java and a tester class MyIterableTester.java.
🌐
TutorialsPoint
tutorialspoint.com › what-is-iterable-interface-in-java
What is Iterable Interface in Java?
August 17, 2023 - In this example, we will use the forEach() in the place of iterator() method and for-each loop to get the desired result. import java.util.*; public class ArrayObj { public static void main(String[] args) { // Creating arraylist ArrayList<Integer> araylist = new ArrayList<>(); // Adding elements in arraylist araylist.add(1); araylist.add(2); araylist.add(1); araylist.add(0); araylist.add(9); araylist.add(6); System.out.println("Elements of the list: "); // forEach to iterate through elements araylist.forEach(newArraylist -> // printing the elements System.out.println(newArraylist)); } }
Find elsewhere
🌐
Medium
medium.com › javarevisited › iterate-over-any-iterable-in-java-bec78eeeb452
Iterate over any Iterable in Java | by Donald Raab | Javarevisited
3 days ago - Browse the Javadoc below to find out what methods are available. ... A more compact view of the methods on Iterate is available by using the Structure view in IntelliJ. There are over 130 methods available on the Iterate class. I include a code example of a method from the Iterate class contained ...
🌐
GeeksforGeeks
geeksforgeeks.org › java › iterable-foreach-method-in-java-with-examples
Iterable forEach() Method in Java - GeeksforGeeks
July 11, 2025 - It provides a simple way to iterate ... method reference. Example 1: This example demonstrates iterating over a List using an Iterator to print each element of the list....
🌐
W3Schools
w3schools.com › java › java_iterator.asp
Java Iterator
An Iterator is an object that can be used to loop through collections, like ArrayList and HashSet.
Top answer
1 of 6
37

Variables

I understand why you have the Range.this.end and Range.this.start to avoid confusion about where those variables come from... If you need the Range.this as part of the teaching exercise, then sure. Otherwise, I would recommend three things....

  1. add range as a prefix, even though it is slightly redundant
  2. Make them final...
  3. one variable per line... (it makes revision-control diffs/patches easier to read)

The code would look like:

private final int rangeStart;
private final int rangeEnd;

Then, all the Range.this.start would be just rangeStart, etc.

Nested classes

Your iterator class is a non-static class, so it can reference the outer class's range start/end.

In this case, the nested class can be changed to a static class very easily. This has the potential of simplifying memory management because the iterator does not need a reference to the enclosing Range.

Consider a private-static Iterator instance:

// Inner class example
private static final class RangeIterator implements
                Iterator<Integer> {
    private int cursor;
    private final int end;

    public RangeIterator(int start, int end) {
        this.cursor = start;
        this.end = end;
    }

    public boolean hasNext() {
        return this.cursor < end;
    }

    public Integer next() {
        if(this.hasNext()) {
            int current = cursor;
            cursor ++;
            return current;
        }
        throw new NoSuchElementException();
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}

This static class removes the need for the back-references to Range.this entirely....

The new iterator is called simply with:

public Iterator<Integer> iterator() {
    return new RangeIterator(start, end);
}

Pre-Validate

It is better to pre-validate state, than to fall-through to an error... This code:

    public Integer next() {
        if(this.hasNext()) {
            int current = cursor;
            cursor ++;
            return current;
        }
        throw new NoSuchElementException();
    }

would be better as:

    public Integer next() {
        if(!this.hasNext()) {
            throw new NoSuchElementException();
        }
        int current = cursor;
        cursor ++;
        return current;
    }

Post-Increment

This block can be simplified:

        int current = cursor;
        cursor ++;
        return current;

to just:

return cursor++;

although I imagine this is done as an education ploy.

Integer as the example

Because of the int autoboxing I worry that Integer may not be the right choice for data type. You may want to consider a non-primitive as the data.

Autoboxing is the sort of thing that will confuse.

Conclusion

Otherwise, I don't see much in the way of problems.

2 of 6
13

Overall, it's pretty good code to learn from.

Functionality

I like that you've used the inclusive-exclusive convention for the lower and upper bounds, respectively. The rationale for that design would be an interesting discussion topic.

I suggest adding a second constructor for convenience:

public Range(int end) {
    this(0, end);
}

There should probably be getters for start() and end(). Technically, you should override .equals() and .hashCode() as well, but maybe it's OK to leave them out for simplicity.

Style

As @rpg711 noted, putting the @Override annotation everywhere would be good practice. It would also help students see which methods are mandatory parts of the interface (well, practically all of them).

JavaDoc would be a good habit to teach. At the least, document the outer class and inner class, and probably their constructors as well.

It would be more conventional to put a space after the if, for, and while keywords. They look less like function calls that way.

Declaring start and end as final could help emphasize to students that the Range is immutable, and only the RangeIterator changes state. Perhaps adding final would alleviate some of @rolfl's concerns about the inner class referring to Range.this.start and Range.this.end.

In agreement with @rolfl, I would also personally prefer

    @Override
    public Integer next() {
        if (!this.hasNext()) {
            throw new NoSuchElementException();
        }
        // The post-increment magically takes effect _after_
        // returning.  This is equivalent to
        //
        //     int value = this.cursor++;
        //     return value;
        //
        return this.cursor++;
    }

… though I can understand if you choose not to burden the students with that trivia.

Test case

It would be useful to illustrate that two RangeIterators keep state independently. Perhaps this might make a good example?

Range digits = new Range(0, 10);
for (Integer tensDigit : digits) {
    for (Integer onesDigit : digits) {
        System.out.format("%s%s ", tensDigit, onesDigit);
    }
    System.out.println();
}
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-implementing-iterator-and-iterable-interface
Java | Implementing Iterator and Iterable Interface - GeeksforGeeks
July 11, 2025 - These two functions form the core of Iterable and Iterator interface. ... import java.util.Iterator; // Custom Linked List class using Generics class List<T> implements Iterable<T> { Node<T> head, tail; // add new Element at tail of the linked list in O(1) public void add(T data) { Node<T> node = new Node<>(data, null); if (head == null) tail = head = node; else { tail.setNext(node); tail = node; } } // return Head public Node<T> getHead() { return head; } // return Tail public Node<T> getTail() { return tail; } // return Iterator instance public Iterator<T> iterator() { return new ListIterato
🌐
YouTube
youtube.com › watch
Using the Iterable Interface in Java - YouTube
0:09 - Overview of the Iterable interface0:36 - Iterable interface methods1:02 - Example of using an Iterable object - using the Iterator returned by iterato...
Published: October 9, 2021
🌐
YouTube
youtube.com › watch
Java Iterable - YouTube
The Java Iterable interface, java.util.Iterable, represents a collection of element (objects) which can be iterated. You can iterate the elements of a Java I...
Published: May 25, 2020
🌐
Java
download.java.net › java › early_access › panama › docs › api › java.base › java › lang › Iterable.html
Iterable (Java SE 19 & JDK 19 [build 1])
Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Actions are performed in the order of iteration, if that order is specified.
🌐
Stack Abuse
stackabuse.com › java-iterable-interface-iterator-listiterator-and-spliterator
Java Iterable Interface: Iterator, ListIterator, and Spliterator
September 12, 2019 - Simple loop example: Ant-Man Black Widow Captain America Doctor Strange Exception in thread "main" java.util.ConcurrentModificationException · This is where iterators come in handy, acting as a middle-man to remove the element from the collection but also to ensure that the traversal continues as planned: