Can we write our own iterator in Java? Can we write our own iterator in Java? java java

Can we write our own iterator in Java?


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 iteratorwhile (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.


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.


Good example for Iterable to compute factorial

FactorialIterable fi = new FactorialIterable(10);Iterator<Integer> iterator = fi.iterator();while (iterator.hasNext()){     System.out.println(iterator.next());}

Short code for Java 1.8

new FactorialIterable(5).forEach(System.out::println);

Custom Iterable class

public class FactorialIterable implements Iterable<Integer> {    private final FactorialIterator factorialIterator;    public FactorialIterable(Integer value) {        factorialIterator = new FactorialIterator(value);    }    @Override    public Iterator<Integer> iterator() {        return factorialIterator;    }    @Override    public void forEach(Consumer<? super Integer> action) {        Objects.requireNonNull(action);        Integer last = 0;        for (Integer t : this) {            last = t;        }        action.accept(last);    }}

Custom Iterator class

public class FactorialIterator implements Iterator<Integer> {    private final Integer mNumber;    private Integer mPosition;    private Integer mFactorial;    public FactorialIterator(Integer number) {        this.mNumber = number;        this.mPosition = 1;        this.mFactorial = 1;    }    @Override    public boolean hasNext() {        return mPosition <= mNumber;    }    @Override    public Integer next() {        if (!hasNext())            return 0;        mFactorial = mFactorial * mPosition;        mPosition++;        return  mFactorial;    }}