Переход от итератора к для каждого

У меня есть функция panel1, которая возвращает итератор, работающий со следующей программой:

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
}

Для простоты я хочу облегчить это, используя синтаксис foreach Java, как показано в следующем примере.

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

Вот класс Panel, который я сделал до сих пор с анонимным классом:

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
    }
}

Хорошо, хорошее заявление. Но у вас есть вопрос?

vincrichaud 27.05.2019 11:18
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
67
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Используйте Iterable вместо Iterator в сигнатуре метода:

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

}
Ответ принят как подходящий

Iterator не являются Iterable в Java, как в некоторых других языках, поэтому вам нужно, чтобы panel1 возвращал Iterable<Integer>, а не Iterator<Integer>, а затем использовал его непосредственно в расширенном цикле for:

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);
         }
    }
}

Большое спасибо ! Знаете ли вы, как сделать так, чтобы с Panel можно было обращаться как с любым объектом типа List?

Revolucion for Monica 28.05.2019 02:34

@ThePassenger — реализовать Panel интерфейс List.

T.J. Crowder 28.05.2019 10:23

Вам нужно передать Iterable<Integer> в расширенный цикл for, а не Iterator<Integer>.

Например:

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

Вы можете использовать настоящие int с 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

Здесь используются потоки с еще более новой конструкцией для каждого.

IntStream.range(1, 6) будет эквивалентно, 6 будет верхней границей эксклюзивный.

К сожалению, потоки нельзя напрямую использовать в цикле java-5 for-each.

Lino 27.05.2019 11:29

Другие вопросы по теме