Revolucion for Monica
Revolucion for Monica

Reputation: 3296

Shifting from iterator to for each

I have a panel1 function that returns an iterator that works with the following program:

public static void main(String[] args) {

     Iterator<Integer> it = panel1(1,5);
     for(;it.hasNext();)
        System.out.println(it.next()); // return 1 2 3 4 5
}

For simplicity, I want to facilitate this by using the Java foreach syntax as shown in the following example.

for(int i:panel2(1,5))
    System.out.println(i); // would return 1 2 3 4 5

Here is the Panel class I did so far with an anonym class:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Panel{

    public static Iterator<Integer> panel1(final int begin,final int end){
        Iterator<Integer> it = new Iterator<Integer>(){

            private int nextValue = begin;
            private final int max = end;

            public boolean hasNext() {
                return nextValue <= max;
            }

            public Integer next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                return Integer.valueOf(nextValue++);
            }

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

    public static void main(String[] args) {

         Iterator<Integer> it = panel1(1,5);
         for(;it.hasNext();)
            System.out.println(it.next()); // affiche 1 2 3 4 5
    }
}

Upvotes: 1

Views: 73

Answers (4)

Joop Eggen
Joop Eggen

Reputation: 109557

You can use real ints, with IntStream:

IntStream.rangeClosed(1, 5)
    .forEach(System::println):

IntStream.rangeClosed(1, 5)
    .forEach(i -> System.println(i)):

IntStream.rangeClosed(1, 5)
    .forEach(i -> System.println(i)):

IntStream.rangeClosed(1, 5)
    .forEach(i -> {
         System.println(i);
}):


1
2
:
5

This uses Streams, with the even newer forEach construct.

IntStream.range(1, 6) would be equivalent, 6 being the exclusive upper bound.

Upvotes: 1

Eran
Eran

Reputation: 393831

You need to pass Iterable<Integer> to the enhanced for loop, not an Iterator<Integer>.

For example:

public static void main(String[] args) {
    Iterable<Integer> iterable = () -> panel1(1,5);
    for (int i : iterable)
        System.out.println(i);
}

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074335

Iterators are not Iterable in Java as they are in some other languages, so you have to have panel1 return an Iterable<Integer>, not an Iterator<Integer>, and then use it directly in the enhanced for loop:

public class Panel{

    public static Iterable<Integer> panel1(final int begin,final int end){
        return new Iterable<Integer>() {
            public Iterator<Integer> iterator() {
                Iterator<Integer> it = new Iterator<Integer>(){

                    private int nextValue = begin;
                    private final int max = end;

                    public boolean hasNext() {
                        return nextValue <= max;
                    }

                    public Integer next() {
                        if (!hasNext()) {
                            throw new NoSuchElementException();
                        }
                        return Integer.valueOf(nextValue++);
                    }

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

    public static void main(String[] args) {

         for (int i : panel1(1,5)) {
            System.out.println(i);
         }
    }
}

Upvotes: 1

Benoit
Benoit

Reputation: 5394

Use Iterable instead of Iterator in the method signature:

public static Iterable<Integer> panel1(final int begin,final int end) {
  ...
  return () -> it;

}

Upvotes: 1

Related Questions