The best reusable option is to implement the interface Iterable and override the method iterator().

Here's an example of a an ArrayList like class implementing the interface, in which you override the method Iterator().

import java.util.Iterator;

public class SOList<Type> implements Iterable<Type> {

    private Type[] arrayList;
    private int currentSize;

    public SOList(Type[] newArray) {
        this.arrayList = newArray;
        this.currentSize = arrayList.length;
    }

    @Override
    public Iterator<Type> iterator() {
        Iterator<Type> it = new Iterator<Type>() {

            private int currentIndex = 0;

            @Override
            public boolean hasNext() {
                return currentIndex < currentSize && arrayList[currentIndex] != null;
            }

            @Override
            public Type next() {
                return arrayList[currentIndex++];
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
        return it;
    }
}

This class implements the Iterable interface using Generics. Considering you have elements to the array, you will be able to get an instance of an Iterator, which is the needed instance used by the "foreach" loop, for instance.

You can just create an anonymous instance of the iterator without creating extending Iterator and take advantage of the value of currentSize to verify up to where you can navigate over the array (let's say you created an array with capacity of 10, but you have only 2 elements at 0 and 1). The instance will have its owner counter of where it is and all you need to do is to play with hasNext(), which verifies if the current value is not null, and the next(), which will return the instance of your currentIndex. Below is an example of using this API...

public static void main(String[] args) {
    // create an array of type Integer
    Integer[] numbers = new Integer[]{1, 2, 3, 4, 5};

    // create your list and hold the values.
    SOList<Integer> stackOverflowList = new SOList<Integer>(numbers);

    // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
    for(Integer num : stackOverflowList) {
        System.out.print(num);
    }

    // creating an array of Strings
    String[] languages = new String[]{"C", "C++", "Java", "Python", "Scala"};

    // create your list and hold the values using the same list implementation.
    SOList<String> languagesList = new SOList<String>(languages);

    System.out.println("");
    // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
    for(String lang : languagesList) {
        System.out.println(lang);
    }
}
// will print "12345
//C
//C++
//Java
//Python
//Scala

If you want, you can iterate over it as well using the Iterator instance:

// navigating the iterator
while (allNumbers.hasNext()) {
    Integer value = allNumbers.next();
    if (allNumbers.hasNext()) {
        System.out.print(value + ", ");
    } else {
        System.out.print(value);
    }
} 
// will print 1, 2, 3, 4, 5

The foreach documentation is located at http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html. You can take a look at a more complete implementation at my personal practice google code.

Now, to get the effects of what you need I think you need to plug a concept of a filter in the Iterator... Since the iterator depends on the next values, it would be hard to return true on hasNext(), and then filter the next() implementation with a value that does not start with a char "a" for instance. I think you need to play around with a secondary Interator based on a filtered list with the values with the given filter.

Answer from Marcello DeSales on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-implementing-iterator-and-iterable-interface
Java | Implementing Iterator and Iterable Interface - GeeksforGeeks
July 11, 2025 - If the Iterator class is implemented as an inner class, we can simply use "this" keyword (e.g. cursor = CustomDataStructure.this.element) to access the desired element · If the Iterator class is implemented as a separate class, we can pass this object of the data structure to the iterator class constructor as demonstrated in the example below.
Top answer
1 of 6
215

The best reusable option is to implement the interface Iterable and override the method iterator().

Here's an example of a an ArrayList like class implementing the interface, in which you override the method Iterator().

import java.util.Iterator;

public class SOList<Type> implements Iterable<Type> {

    private Type[] arrayList;
    private int currentSize;

    public SOList(Type[] newArray) {
        this.arrayList = newArray;
        this.currentSize = arrayList.length;
    }

    @Override
    public Iterator<Type> iterator() {
        Iterator<Type> it = new Iterator<Type>() {

            private int currentIndex = 0;

            @Override
            public boolean hasNext() {
                return currentIndex < currentSize && arrayList[currentIndex] != null;
            }

            @Override
            public Type next() {
                return arrayList[currentIndex++];
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
        return it;
    }
}

This class implements the Iterable interface using Generics. Considering you have elements to the array, you will be able to get an instance of an Iterator, which is the needed instance used by the "foreach" loop, for instance.

You can just create an anonymous instance of the iterator without creating extending Iterator and take advantage of the value of currentSize to verify up to where you can navigate over the array (let's say you created an array with capacity of 10, but you have only 2 elements at 0 and 1). The instance will have its owner counter of where it is and all you need to do is to play with hasNext(), which verifies if the current value is not null, and the next(), which will return the instance of your currentIndex. Below is an example of using this API...

public static void main(String[] args) {
    // create an array of type Integer
    Integer[] numbers = new Integer[]{1, 2, 3, 4, 5};

    // create your list and hold the values.
    SOList<Integer> stackOverflowList = new SOList<Integer>(numbers);

    // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
    for(Integer num : stackOverflowList) {
        System.out.print(num);
    }

    // creating an array of Strings
    String[] languages = new String[]{"C", "C++", "Java", "Python", "Scala"};

    // create your list and hold the values using the same list implementation.
    SOList<String> languagesList = new SOList<String>(languages);

    System.out.println("");
    // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
    for(String lang : languagesList) {
        System.out.println(lang);
    }
}
// will print "12345
//C
//C++
//Java
//Python
//Scala

If you want, you can iterate over it as well using the Iterator instance:

// navigating the iterator
while (allNumbers.hasNext()) {
    Integer value = allNumbers.next();
    if (allNumbers.hasNext()) {
        System.out.print(value + ", ");
    } else {
        System.out.print(value);
    }
} 
// will print 1, 2, 3, 4, 5

The foreach documentation is located at http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html. You can take a look at a more complete implementation at my personal practice google code.

Now, to get the effects of what you need I think you need to plug a concept of a filter in the Iterator... Since the iterator depends on the next values, it would be hard to return true on hasNext(), and then filter the next() implementation with a value that does not start with a char "a" for instance. I think you need to play around with a secondary Interator based on a filtered list with the values with the given filter.

2 of 6
51

Sure. An iterator is just an implementation of the java.util.Iterator interface. If you're using an existing iterable object (say, a LinkedList) from java.util, you'll need to either subclass it and override its iterator function so that you return your own, or provide a means of wrapping a standard iterator in your special Iterator instance (which has the advantage of being more broadly used), etc.

🌐
Baeldung
baeldung.com › home › java › java collections › creating custom iterator in java
Creating Custom Iterator in Java | Baeldung
June 27, 2025 - The default versions of iterators are only meant to iterate through the underlying collection linearly. It goes from one element to the next using the next() method. We cannot use the default iterators to perform any additional operation on the elements. These are some of the reasons why we might want to implement our iterators:
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › Iterator.html
Iterator (Java Platform SE 8 )
July 21, 2026 - This method can be called only once per call to next(). 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. ... The default implementation throws an instance of UnsupportedOperationException and performs no other action.
🌐
Medium
medium.com › @Neelesh-Janga › iterator-and-iterable-in-java-java-stories-be23f2b73125
Iterator and Iterable in Java — Java Stories | Neelesh J | Medium
July 7, 2024 - It defines a single method, iterator(), ... loop) or manually with an Iterator object. By implementing Iterable, a class signals that it can provide an iterator to iterate over its elements....
Find elsewhere
🌐
Jenkov
jenkov.com › tutorials › java-collections › iterator.html
Java Iterator
As you can see, the example first iterates the ListIterator forward through all the elements, and then backwards again through all the elements back to the first element. If you have a special, custom made type of collection, you can implement the Java Iterator interface yourself to create an Iterator that can iterate through the elements of your custom collection.
🌐
Refactoring.Guru
refactoring.guru › home › design patterns › behavioral patterns
Iterator
January 1, 2026 - The return type should be equal to that of the iterator interface. You may declare similar methods if you plan to have several distinct groups of iterators. Implement concrete iterator classes for the collections that you want to be traversable with iterators.
🌐
W3Schools
w3schools.com › java › java_iterator.asp
Java Iterator
To use an Iterator, you must import it from the java.util package.
🌐
Baeldung
baeldung.com › home › java › java collections › a guide to iterator in java
A Guide to Iterator in Java | Baeldung
June 27, 2025 - An Iterator is one of many ways we can traverse a collection, and as every option, it has its pros and cons. It was first introduced in Java 1.2 as a replacement of Enumerations and:
🌐
Medium
medium.com › @toimrank › java-iterator-1cc0dbce8e95
Java Iterator. Iterator interface belongs to java.util… | by Imran Khan | Medium
October 10, 2022 - Iterator interface belongs to java.util package and it is a part of Collection framework. Iterator interface allows us to iterate over…
🌐
Quora
quora.com › How-can-you-implement-an-iterator-in-Java
How to implement an iterator in Java - Quora
Answer (1 of 3): An iterator? As in, something that can iterate over an object? The simple pithy answer is of course: Implement the Iterator interface. See the JavaDoc for details: Iterator (Java SE 9 & JDK 9 ) Of course, you might also want to do this: Write some sort of class that can be iter...
🌐
GeeksforGeeks
geeksforgeeks.org › java › iterators-in-java
Iterator in Java - GeeksforGeeks
Iterator is part of the java.util package and is used by collection classes to traverse elements. Collection classes implement the Iterable interface, which provides the iterator() method that returns an Iterator object.
Published: 2 weeks ago
🌐
Reddit
reddit.com › r/javahelp › i'm somewhat confused about difference between iterator and iterable
r/javahelp on Reddit: I'm somewhat confused about difference between Iterator and Iterable
November 23, 2017 -

so I know how to implement (e.g public Iterator<E> iterator() { return new ListIterator<E>(//could add first element here); }

but sometimes I see it saying public iterable. what's the difference? I think it is iterator is like you go through it once and you're done but iterable you get back a list that you can go through over and over again?

if it helps the thing I'm having trouble about is this: http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html

public Iterable<Board> neighbors() 

do I just have to return a linked list of some sort (stack/queue)? why not use iterator<Board> instead?

Edit: I got it, you're returning an object that is iterable itself.

🌐
Tutorialspoint
tutorialspoint.com › java › java_using_iterator.htm
Java - How to Use Iterator?
In general, to use an iterator to cycle through the contents of a collection, first import the java.util.Iterator library, and then follow these steps −
🌐
GeeksforGeeks
geeksforgeeks.org › java › iterator-interface-in-java
Iterator Interface In Java - GeeksforGeeks
July 23, 2025 - Example: Implementation of Iterator · All classes in the Collection Framework provide iterator() method which returns the instance of Iterator to iterate over the elements in that collection. Java ·
🌐
DigitalOcean
digitalocean.com › community › tutorials › iterator-design-pattern-java
Iterator Design Pattern in Java | DigitalOcean
August 3, 2022 - Technical tutorials, Q&A, events — This is an inclusive place where developers can find or lend support and discover new ways to contribute to the community.
🌐
Reddit
reddit.com › r/javahelp › is my understanding of iterators and iterable correct?
r/javahelp on Reddit: Is my understanding of Iterators and Iterable correct?
April 23, 2019 -

Hi,

According to my understanding of Iterator and Iterable:

  1. Iterable is used when you want to get for - each for a collection. Iterator is still used behind the scenes to fetch the items for for-each.

  2. If I just want to go through a collection ( don't want for-each) , I can just implement Iterator interface on collection class and it should work. Note - Iterable is not necessary.

  3. If I implement Iterator interface on a collection class, It gives me the ability to iterate over the collection . Now if I implement the 'for-each' method (defined in Iterable Interface ) in the class , then I can get a for-each loop for the collection , even without implementing Iterable.

is it correct?

Thanks

Top answer
1 of 4
6
Iterable is a functional interface that outlines what an iterator is. Iterator is an interface that outlines methods to be used in the iterator. Java Collections come with iterators, which means they implement Iterable already. You can make your own data structure and define an iterator for it if you like. Iterable is used when you want to get for - each for a collection. Iterator is still used behind the scenes to fetch the items for for-each. An iterator is used to get the items. That iterator is created by using the Iterator interface [ ie- Iterator itr = yourList.iterator() ]. That data structure (list) implements Iterable, which is why it has an iterator() method. If I just want to go through a collection ( don't want for-each) , I can just implement Iterator interface on collection class and it should work. Note - Iterable is not necessary. You're confused as to what Iterable, Iterator, and iterator() do. If you want to iterate through a Collection without using a for-each style implementation, use the good ole for loop. If I implement Iterator interface on a collection class, It gives me the ability to iterate over the collection . Now if I implement the 'for-each' method (defined in Iterable Interface ) in the class , then I can get a for-each loop for the collection , even without implementing Iterable. Is this a question? Iterable is already implemented in every Java Collection.
2 of 4
3
The for-each statement (for(var element : elements)...) can iterate over the elements of arrays or, via an Iterator the elements of an Iterable. Whilst you do not have to implement Iterable (that is, you can just supply an iterator), it's trivially easy to do so. If you implement Iterator iterator() and Iterable then you get forEach(Consumer) for free as it's a default method of Iterable - though you could choose to implement a more efficient option that doesn't use an iterator at all. If you're implementing a java.util.Collection class then you have no choice but to also implement Iterable as it is a sub-interface of Iterable.
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();
}