Вопрос

Я только что узнал о том, как Java Collections Framework реализует структуры данных в связанных списках.Насколько я понимаю, Iterators — это способ перемещения по элементам структуры данных, такой как список.Почему используется этот интерфейс?Почему методы hasNext(), next() и remove() не закодирован напрямую в самой реализации структуры данных?

С сайта Java: текст ссылки

Итератор общедоступного интерфейса<E>

Итератор над коллекцией.Итератор занимает место перечисления в рамках коллекций Java.Итераторы отличаются от перечисления двумя способами:

  • Итераторы позволяют абоненту удалять элементы из базовой коллекции во время итерации с четко определенной семантикой.
  • Названия методов были улучшены.
Этот интерфейс является членом фреймворта с коллекциями Java.

Я пробовал гуглить и не нашел однозначного ответа.Может ли кто-нибудь пролить свет на то, почему Sun решила их использовать?Это из-за лучшего дизайна?Повышенная безопасность?Хорошая практика объектно-ориентированного проектирования?

Любая помощь будет оценена.Спасибо.

Это было полезно?

Решение

Почему используется этот интерфейс?

Потому что он поддерживает базовые операции, которые позволяют клиентскому программисту перебирать любую коллекцию (примечание:не обязательно Collection в Object смысл).

Почему методы...Не напрямую кодируется самой реализации структуры данных?

Да, они просто помечены как «Частные», так что вы не сможете залезть в них и поиграть с ними.Более конкретно:

  • Вы можете реализовать или создать подкласс Iterator так, что он делает то, чего не делают стандартные, без необходимости изменять фактический объект, над которым он выполняет итерацию.
  • Интерфейсы объектов, которые можно обходить, не должны быть загромождены методами обхода, в частности любыми узкоспециализированными методами.
  • Вы можете раздать Iterators любому количеству клиентов, которое вы пожелаете, и каждый клиент может перемещаться в свое время и со своей скоростью.
  • Джава Iterators из пакета java.util, в частности, выдаст исключение, если хранилище, в котором они хранятся, было изменено, пока у вас все еще есть Iterator вне.Это исключение позволяет вам знать, что Iterator теперь может возвращать недопустимые объекты.

Для простых программ все это, вероятно, не имеет смысла.Однако сложность, которая делает их полезными, быстро обнаружится.

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

Ты спрашиваешь:«Почему методы hasNext(), next() и Remove() не закодированы напрямую в самой реализации структуры данных?».

Платформа коллекций Java решает определить интерфейс Iterator как внешний для самой коллекции.Обычно, поскольку каждая коллекция Java реализует Iterable интерфейс, программа Java вызовет iterator создать собственный итератор, чтобы его можно было использовать в цикле.Как отмечали другие, Java 5 позволяет нам управлять использованием итератора с помощью цикла for-each.

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

В классической книге GoF контраст между внутренними и внешними итераторами прописан довольно четко.

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

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

Пример работы внутренних итераторов см. в разделе Ruby. Enumerable API, который имеет внутренние методы итерации, такие как each.В Ruby идея состоит в том, чтобы передать блок кода (т.замыкание) внутреннему итератору, чтобы коллекция могла позаботиться о своей собственной итерации.

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

Обратной стороной этого разделения является то, что итератор не знает об изменениях, внесенных в коллекцию, которую он выполняет.поэтому вы не можете изменить структуру коллекции и ожидать, что итератор продолжит свою работу без «жалоб».

Используя Iterator Интерфейс позволяет любому классу, реализующему его методы, выступать в качестве итераторов.Понятие интерфейса в Java заключается в том, что в некотором смысле существует договорное обязательство предоставлять определенные функциональные возможности в классе, который implements интерфейс, чтобы действовать так, как того требует интерфейс.Поскольку договорные обязательства должны быть выполнены, чтобы класс был действительным, другие классы, которые видят этот класс implements интерфейс и, таким образом, уверен, что класс будет иметь определенные функциональные возможности.

В этом примере вместо реализации методов (hasNext(), next(), remove()) в LinkedList сам класс, LinkedList класс объявит, что это implements тот Iterator интерфейс, чтобы другие знали, что LinkedList может использоваться как итератор.В свою очередь, LinkedList класс будет реализовывать методы из Iterator интерфейс (например, hasNext()), поэтому он может функционировать как итератор.

Другими словами, реализация интерфейса — это концепция объектно-ориентированного программирования, позволяющая другим знать, что определенный класс имеет все необходимое, чтобы быть тем, чем он себя называет.

Это понятие реализуется за счет наличия методов, которые должны быть реализованы классом, реализующим интерфейс.Это гарантирует, что другие классы, которые хотят использовать класс, реализующий Iterator интерфейс, что у него действительно будут методы, которые должны быть у Итераторов, такие как hasNext().

Также следует отметить, что, поскольку в Java нет множественного наследования, для эмуляции этой функции можно использовать интерфейс.Реализуя несколько интерфейсов, можно создать класс, который является подклассом и наследует некоторые функции, а также «наследовать» функции другого, реализуя интерфейс.Одним из примеров было бы, если бы я хотел иметь подкласс класса LinkedList класс называется ReversibleLinkedList который может выполняться в обратном порядке, я могу создать интерфейс с именем ReverseIterator и обеспечить, чтобы это обеспечивало previous() метод.Поскольку LinkedList уже реализует Iterator, новый обратимый список реализовал бы как Iterator и ReverseIterator интерфейсы.

Подробнее об интерфейсах можно прочитать здесь. Что такое интерфейс? из Учебного пособия по Java от Sun.

Несколько экземпляров интератора могут использоваться одновременно.Подходите к ним как к локальным курсорам для базовых данных.

КСТАТИ:предпочтение интерфейсов конкретным реализациям приводит к потере связи

Найдите шаблон проектирования итератора и здесь: http://en.wikipedia.org/wiki/Итератор

Потому что вы можете перебирать что-то, что не является структурой данных.Допустим, у меня есть сетевое приложение, которое получает результаты с сервера.Я могу вернуть обертку Iterator вокруг этих результатов и транслируйте их через любой стандартный код, который принимает объект Iterator.

Считайте это ключевой частью хорошего дизайна MVC.Данные должны быть получены из модели (т.е.структура данных) в представление каким-то образом.Использование Итератора в качестве посредника гарантирует, что реализация Модели никогда не будет раскрыта.Вы можете хранить LinkedList в памяти, извлекать информацию из алгоритма дешифрования или упаковывать вызовы JDBC.Для представления это просто не имеет значения, поскольку представление заботится только об интерфейсе Iterator.

Интересная статья, в которой обсуждаются плюсы и минусы использования итераторов:

http://www.sei.cmu.edu/pacc/CBSE5/Sridhar-cbse5-final.pdf

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

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

В конечном счете, потому что Iterator фиксирует абстракцию управления, применимую к большому количеству структур данных.Если вы разбираетесь в теории категорий, эта статья может вас взорвать: Сущность шаблона «Итератор».

Что ж, похоже, что первый пункт позволяет многопоточным (или однопоточным, если вы облажались) приложениям не блокировать коллекцию из-за нарушений параллелизма.Например, в .NET вы не можете перечислять и изменять коллекцию (или список, или любой IEnumerable) одновременно без блокировки или наследования от IEnumerable и переопределения методов (мы получаем исключения).

Итератор просто добавляет общий способ просмотра коллекции элементов.Одной из приятных функций является функция i.remove(), с помощью которой вы можете удалять элементы из списка, который вы перебираете.Если бы вы просто попытались удалить элементы из списка в обычном режиме, это привело бы к странным эффектам или выдаче и исключению.

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

Итераторы — один из многих шаблонов проектирования, доступных в Java.Шаблоны проектирования можно рассматривать как удобные строительные блоки, стили, использование вашего кода/структуры.

Чтобы узнать больше о шаблоне проектирования «Итератор», посетите этот веб-сайт, на котором рассказывается об «Итераторе», а также о многих других шаблонах проектирования.Вот фрагмент с сайта Iterator: http://www.patterndepot.com/put/8/Behavioral.html

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

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

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

Итератор полезен, когда вы имеете дело с коллекциями в Java.

Использовать Для каждого цикл (Java1.5) для перебора коллекции, массива или списка.

Интерфейс java.util.Iterator используется в Java Collections Framework, чтобы разрешить изменение коллекции во время ее итерации.Если вы просто хотите аккуратно перебрать всю коллекцию, используйте вместо этого for-each, но преимуществом итераторов является функциональность, которую вы получаете:необязательная операция удаления() и, что еще лучше, для интерфейса List Iterator, который также предлагает операции add() и set().Оба этих интерфейса позволяют вам перебирать коллекцию и одновременно изменять ее структуру.Попытка изменить коллекцию во время итерации по ней с помощью for-each приведет к возникновению исключения ConcurrentModificationException, обычно из-за неожиданного изменения коллекции!

Взгляните на класс ArrayList.

В нем есть 2 частных класса (внутренние классы), называемые ITR и ListItr

Они реализуют интерфейсы Iterator и ListIterator соответственно.

публичный класс ArrayList.....{ // включающий класс

  private class Itr implements Iterator<E> {

        public E next() {
            return ArrayList.this.get(index++); //rough, not exact
        }

        //we have to use ArrayList.this.get() so the compiler will
        //know that we are referring to the methods in the 
        //enclosing ArrayList class

        public void remove() {
            ArrayList.this.remove(prevIndex);
        }

        //checks for...co mod of the list
        final void checkForComodification() {  //ListItr gets this method as well
             if (ArrayList.this.modCount != expectedModCount) { 
                 throw new ConcurrentModificationException();
             }
        }
  }

  private class ListItr extends Itr implements ListIterator<E> {
         //methods inherted....
        public void add(E e) {
            ArrayList.this.add(cursor, e);
        }

        public void set(E e) {
            ArrayList.this.set(cursor, e);
        }
  }

}

Когда вы называете методы iterator () и listiceTerator (), они возвращают новый экземпляр частного класса ITR или ListItr, и, поскольку эти внутренние классы находятся «внутри» класса ArrayList, они могут свободно изменять ArrayList без запуска совместного использования. , если только вы не измените список одновременно (согласованно) через set () add () или удалить () методы класса ArrayList.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top