Range Over Iterators in Java

Starting with version 1.23, iterators have been added to facilitate ranging over various collections. Here is an example translated into Java.

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Consumer;

public class List<T> {
    private Element<T> head, tail;

    private static class Element<T> {
        T value;
        Element<T> next;

        Element(T value) {
            this.value = value;
        }
    }

    public void push(T value) {
        Element<T> newElem = new Element<>(value);
        if (tail == null) {
            head = tail = newElem;
        } else {
            tail.next = newElem;
            tail = newElem;
        }
    }

    public Iterable<T> all() {
        return () -> new Iterator<>() {
            private Element<T> current = head;

            @Override
            public boolean hasNext() {
                return current != null;
            }

            @Override
            public T next() {
                if (current == null) throw new NoSuchElementException();
                T value = current.value;
                current = current.next;
                return value;
            }
        };
    }

    public static void main(String[] args) {
        List<Integer> list = new List<>();
        list.push(10);
        list.push(13);
        list.push(23);

        // Iterating over the elements
        for (Integer element : list.all()) {
            System.out.println(element);
        }

        // Collecting all elements to a list
        java.util.List<Integer> collected = new java.util.ArrayList<>();
        list.all().forEach(collected::add);
        System.out.println("all: " + collected);

        // Generating Fibonacci numbers
        Iterable<Integer> fib = genFib();
        for (Integer n : fib) {
            if (n >= 10) break;
            System.out.println(n);
        }
    }

    public static Iterable<Integer> genFib() {
        return () -> new Iterator<>() {
            private int a = 1, b = 1;

            @Override
            public boolean hasNext() {
                return true;
            }

            @Override
            public Integer next() {
                int temp = a;
                a = b;
                b = temp + b;
                return temp;
            }
        };
    }
}

In this example:

  • The List class manages a single-linked list where elements can be added using the push method.
  • The all method returns an Iterable of type T, which allows for the use of a Java enhanced for-loop (for-each loop).
  • The genFib method generates an infinite sequence of Fibonacci numbers using an Iterator.

This example demonstrates how you can handle ranges and iteration in Java using Iterator, Iterable, and the enhanced for-loop to iterate through collections. We also showcased how the Fibonacci sequence can be generated as an infinite iterator.