4

I have to make a custom iterator that iterators through an array endlessly. I have no clue how to do this considering I've never worked with iterators in java before. If anyone could help me out at all and explain to me, I'd appreciate it very much.

public class Numbers{   
private int[] array;

public Numbers(int[] array){ 
    this.array = array
}
    public static void main(String[] args) {

        Numbers n = new Numbers();
        Iterator num = n.sequence();
        for(int i = 0; i < 10; i++){
            if (num.hasNext()){
                System.out.print(num.next() + " ");
                System.out.println();
            }
        }
    }
}
Tim
  • 35,413
  • 11
  • 95
  • 121
  • 1
    You should show us the code for your Numbers class. Also, if this is homework you should tag it as such. – kurtzbot Sep 05 '12 at 23:19
  • @kurtzbot I suspect we're already looking at the entire Numbers class... – Ted Sep 05 '12 at 23:23
  • Iterators are by definition "finite" in size. I suppose you could wrap the for loop inside of a 'for ( ; ; )' loop ? – djangofan Sep 05 '12 at 23:30
  • Also, I can not change any of the code currently in main. I can however, add to it. –  Sep 05 '12 at 23:38
  • @djangofan, actually you can override the next() method and have it return an "infinite" set of data based on the current index. Just look at A. R. S.'s answer for an example. – kurtzbot Sep 05 '12 at 23:50

3 Answers3

4

See below:

public class Numbers implements Iterable<Integer> {
    private int[] array;
    private int i;
    public Numbers(int[] array) { 
        this.array = array;
        i = 0; 
    }

    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            @Override
            public boolean hasNext() { return true; }

            @Override
            public Integer next() {
                int j = i;
                i = (i + 1) % array.length;
                return array[j];
            }

            @Override
            public void remove() {}
        };
    }
}

You could then do:

Numbers n = new Numbers(new int[]{1,2,3});
for (int i : n)
    System.out.println(i);  // or anything else

This would result in the infinite loop:

1
2
3
1
2
3
1
2
...

Relevant javadocs:
- Iterator
- Iterable


Another way to do it is just to have an infinite while-loop as such:
int[] array = new int[]{1, 2, 3};
int i = 0;
while (true) {
    System.out.println(array[i]);  // or anything else
    i = (i + 1) % array.length;
}
arshajii
  • 127,459
  • 24
  • 238
  • 287
  • See also [*What code does the compiler generate for autoboxing?*](http://stackoverflow.com/q/408661/230513) – trashgod Sep 05 '12 at 23:35
  • Wouldn't the code for next in this solution be public int getNext()? Or am I just missing something? –  Sep 05 '12 at 23:43
  • `int` wouldn't work in this case, you need the `Integer` wrapper class to properly override the `next` method of the `Iterator` interface. – arshajii Sep 05 '12 at 23:46
  • The [`Iterator`](http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html) interface specifies `next()`. – trashgod Sep 05 '12 at 23:47
  • Alright, I understand now. Thanks for the help. Still kinda shaky on the modulus thing but I'll figure it out I suppose. –  Sep 05 '12 at 23:51
  • The modulus thing is to wrap the index back around back to 0 when it goes out of range. For example, with {1, 2, 3} (length = 3), we start at `i` = 0, next we have `i` = (0 + 1) % 3 = 1, next `i` = (1 + 1) % 3 = 2, and then `i` = (2 + 1) % 3 = 0, - see how we came back to 0? Now the cycle can start again. – arshajii Sep 06 '12 at 00:00
1

This is basically how an iterator works. This example uses a List, but you can use an iterator against any collection that implements java.lang.Iterable.

List<String> someList; // assume this has been instantiated and has values in it

ListIterator<String> it = someList.listIterator();
while (it.hasNext()) {
    String value = it.next();

    // do something with value
}

Pretty much, you instantiate the iterator by telling the collection to give you a reference to its iterator. Then you loop by calling hasNext(), which will keep you going until you have no more elements. The call to next() pulls the next item from the iterator and increments its position by one. A call to remove() will remove from the list the last item returned by next() (or previous().)

Note, of course, that I've been using java.util.ListIterator instead of java.util.Iterator because the ListIterator is a special implementation of Iterator optimized for use against lists, like in the example I gave above.

You cannot use an iterator against an array. You'd need to use a vanilla for-loop or convert it into a List or another object that implements Iterable.

To loop through the above list endlessly, your loop would look something like this:

while(it.hasNext()) {
    String value = it.next();

    // do processing

    if (!it.hasNext()) {
        it = someList.listIterator(); // reset the iterator
    }
}

To loop through the array using a for-loop endlessly:

for (int i = 0; i < myArray.length; i++) {
    myArray[i];
    // do something

    if (i == myArray.length - 1) {
        i = 0; // reset the index
    }
}

Alteratively you could have your Numbers class implement Iterable directly.

Roddy of the Frozen Peas
  • 14,380
  • 9
  • 49
  • 99
0

Work with iterators is basically always the same.

First get the iterator from your array:

Iterator iterator = yourArray.iterator();

Second iterate while it has items:

while(iterator.hasNext()) {
  Object element = iterator.next(); 
}
Roddy of the Frozen Peas
  • 14,380
  • 9
  • 49
  • 99