Внешний итератор против внутреннего итератора

Что такое внешний и внутренний итераторы в Java?

Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Лучшая компания по разработке спортивных приложений
Лучшая компания по разработке спортивных приложений
Ищете лучшую компанию по разработке спортивных приложений? Этот список, несомненно, облегчит вашу работу!
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
Деревья поиска (Алгоритм4 Заметки к учебнику)
Деревья поиска (Алгоритм4 Заметки к учебнику)
(1) Двоичные деревья поиска: среднее lgN, наихудшее N для вставки и поиска.
35
0
17 739
6

Ответы 6

Это про кто контролирует итерацию.

Остальные подробности в этом вопросе Каковы преимущества интерфейса Iterator в Java?

Нашел вот такой описание:

Внешние и внутренние итераторы.

Внешние итераторы - когда итерация контролируется объектом коллекции, мы говорим, что у нас есть внешний итератор.

В таких языках, как .net или java, очень легко создавать внешние итераторы. В нашей классической реализации реализован внешний итератор. В следующем примере используется внешний итератор:

// using iterators for a clloection of String objects:
// using in a for loop
for (Iterator it = options.iterator(); it.hasNext(); ) {
   String name = (String)it.next();
   System.out.println(name);
}

// using in while loop
Iterator name = options.iterator();
    while (name.hasNext() ){
      System.out.println(name.next() );
    }

// using in a for-each loop (syntax available from java 1.5 and above)
    for (Object item : options)
        System.out.println(((String)item));

Внутренние итераторы - когда итератор управляет им, у нас есть внутренний итератор.

С другой стороны, реализация и использование внутренних итераторов действительно сложно. Когда используется внутренний итератор, это означает, что запускаемый код делегируется агрегатному объекту. Например, в языках, которые предлагают поддержку для этого, легко вызвать внутренние итераторы:

collection do: [:each | each doSomething] (Smalltalk)  

Основная идея - передать код для выполнения в коллекцию. Затем коллекция вызовет внутренний метод doSomething для каждого из компонентов. В C++ можно отправить метод doMethod как указатель. В C#, .NET или VB.NET можно отправить метод как делегат. В java необходимо использовать шаблон проектирования Functor. Основная идея - создать базовый интерфейс только с одним методом (doSomething). Затем метод будет реализован в классе, реализующем интерфейс, и этот класс будет передан в коллекцию для выполнения итерации. Дополнительные сведения см. В шаблоне проектирования Functor.

Внешний итератор

Когда вы получаете итератор и переступаете через него, это внешний итератор.

for (Iterator iter = var.iterator(); iter.hasNext(); ) {
  Object obj = iter.next();
  // Operate on obj
}

Внутренний итератор

Когда вы передаете объект функции методу для выполнения по списку, это внутренний итератор.

var.each( new Functor() {
  public void operate(Object arg) {
    arg *= 2;
  }
});

Поскольку в Java 5 предпочтительным способом использования внешних итераторов было бы использование цикла for-each: for (Объект o: var) {// NOOP}, хотя это просто синтаксический сахар для явного итератора, использующего версию.

Alex 20.04.2014 21:25

@JohannZacharee не рассматривается как цикл foreach как внутренний итератор, поскольку у нас нет контроля над итератором?

denis631 05.09.2015 13:46

@ denis631 Да, я согласен, что цикл foreach действует аналогично внутреннему итератору. Я не использовал его в качестве примера, так как я понимаю, что Java преобразует их во внешний итератор во время компиляции. Я выбрал функциональный пример, чтобы более наглядно проиллюстрировать различия.

Johann Zacharee 11.09.2015 03:09

Я должен сообщить вам, что этот вопрос теперь является вторым результатом в Google для «внутреннего внешнего итератора», и отрывок гласит, что «быстрый поиск в Google мог бы дать вам ответ: ...» без включения ни одного ответа

Eevee 13.11.2016 03:34

Удалена ссылка на поиск Google, переформатирована, поэтому, надеюсь, результаты Google теперь будут включать соответствующий контент в отрывке.

Johann Zacharee 14.11.2016 21:36

Внешний итератор: - Используя это, мы должны перебирать все элементы один за другим и выполнять некоторую операцию, потому что у программиста есть контроль над этим, это внешний итератор.

Внутренний итератор: - Используя это, мы можем выполнять итерацию в соответствии с нашим условием, Программист может контролировать это, это внутренний итератор.

Давайте посмотрим на один пример ниже: Q - мы хотим добавить сумму к целому числу из списка, которое равно или больше 5.

package java8;

import java.util.ArrayList;
import java.util.List;

public class IteratorExpr {

    public static void main(String[] args) {
        List<Integer> myList = new ArrayList<Integer>();
        for(int i=0; i<10; i++) myList.add(i);

        //Get sum of all value which is more than 5 using External Iterator
        int sum = 0;
        for(int no: myList) {
            if (no >=5) {
                sum += no;
            }
        }
        System.out.println("Sum of numbers using External api : "+sum);

        int summ = myList.stream()
                .filter(p->p>=5)
                .mapToInt(p->p).sum();
        System.out.println("Sum of numbers using internal api : "+summ);
    }

}

Выход :

Sum of numbers using External api : 35
Sum of numbers using internal api : 35

Я нашел ответ через здесь.

Внутренние итераторы управляют итерациями в фоновом режиме. Это оставляет программисту просто декларативно кодировать то, что должно быть сделано с элементами коллекции, вместо того, чтобы управлять итерацией и следить за тем, чтобы все элементы обрабатывались один за другим. Бывший:

public class InternalIterator {

   public static void main(String args[]){

      List<String> namesList=Arrays.asList("Tom", "Dick", "Harry");

      namesList.forEach(name -> System.out.println(name));//Internal Iteration

   }

}

При использовании внешних итераторов ответственность за повторение элементов и обеспечение того, чтобы эта итерация учитывала общее количество записей, наличие дополнительных записей для повторения и т. д., Лежит на программисте.

Бывший:

import java.util.*;

public class ExternalIterator {

   public static void main(String args[]){
      List<String> namesList=Arrays.asList("Tom", "Dick", "Harry");
      for(String name:namesList){
         System.out.println(name);
      }

   }

}

Пример внешнего итератора:

int count = 0;
Iterator<SomeStaff> iterator = allTheStaffs.iterator();
while(iterator.hasNext()) {
    SomeStaff staff = iterator.next();
    if (staff.getSalary() > 25) {
        count++;
    }
}

Пример внутреннего итератора:

long count = allTheStaffs.stream()
                         .filter(staff -> staff.getSalary() > 25)
                         .count();

В изображениях:

Очень красивый образ!

Philippe Fanaro 22.01.2020 18:09

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