Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Итераторы

Читайте также:
  1. Cборщики и итераторы

В любом контейнерном классе вы должны иметь способ поместить вещь внутри и способ достать вещь наружу. Кроме этого, первичная задача контейнера — хранить вещи. В случае ArrayList: add() - способ, который вставляет объекты, а get() - один из способов получит вещи наружу. ArrayList достаточно гибок, вы можете выбрать все что угодно в любое время и выбирать различные элементы одновременно, используя разные индексы.

Если вы хотите начать думать на более высоком уровне, то есть препятствие: вам необходимо знать точный тип контейнера для правильного его использования. Сначала это может не показаться плохим, но что, если вы начнете использовать ArrayList, а позже в вашей программе вы обнаружите, что в связи со способом использования контейнера более эффективным будет использование LinkedList вместо него? Или, предположим, вы хотите написать кусок общего кода, который не будет знать или заботится о типе контейнера, с которым он работает, так что может ли он использовать разные типы контейнеров без переписывания кода?

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

Java Iterator - это пример итератора с такого рода ограничениями. Вы многое можете делать с ним, включая:

  1. Просить контейнер передать вам Iterator, используя метод, называемый iterator(). Этот Iterator будет готов к возврату первого элемента последовательности при первом вызове метода next().
  2. Получать следующий объект в последовательности с помощью next().
  3. Проверять есть ли еще объекты в последовательности с помощью hasNext().
  4. Удалять последний элемент, возвращенный итератором, с помощью remove().

Это все. Это простая реализация итератора, но достаточно мощная (и существуют более изощренный ListIterator для List). Чтобы посмотреть, как это работает, позвольте вновь использовать программу CatsAndDogs.java, введенную ранее в этой главе. В оригинальной версии метод get() был использован для выбора каждого элемента, но в следующей измененной версии используется итератор:

//: c09:CatsAndDogs2.java// Простой контейнер с итератором.import java.util.*; public class CatsAndDogs2 { public static void main(String[] args) { ArrayList cats = new ArrayList(); for(int i = 0; i < 7; i++) cats.add(new Cat(i)); Iterator e = cats.iterator(); while(e.hasNext()) ((Cat)e.next()).print(); }} ///:~

Вы можете видеть, что последние несколько строк используют Iterator, чтобы пройти по последовательности вместо цикла for. С помощью итератора вам нет необходимости заботится о числе элементов в контейнере. Об этом беспокоится за вас hasNext() и next().

В качестве другого примера, рассмотрим создание метода печати общего назначения:

//: c09:HamsterMaze.java// Использование итератора.import java.util.*; class Hamster { private int hamsterNumber; Hamster(int i) { hamsterNumber = i; } public String toString() { return "This is Hamster #" + hamsterNumber; }} class Printer { static void printAll(Iterator e) { while(e.hasNext()) System.out.println(e.next()); }} public class HamsterMaze { public static void main(String[] args) { ArrayList v = new ArrayList(); for(int i = 0; i < 3; i++) v.add(new Hamster(i)); Printer.printAll(v.iterator()); }} ///:~

Пристальнее всмотритесь в метод printAll(). Обратите внимание, что здесь нет информации о типе последовательности. Все что у вас есть - это Iterator, и это все, что вам нужно знать о последовательности: так как вы можете получить следующий объект и так как вы знаете, когда вы подойдете к концу. Эта идея, получение контейнера объектов и прохождение по нему для выполнения операции для каждого элемента - достаточно мощная и будет просматриваться повсюду в этой книге.

Пример является более общим, так как он косвенным образом использует метод Object.toString(). Метод println() перегружается для всех примитивных типов так же, как и для Object; в каждом случае автоматически производится String путем вызова соответствующего метода toString().

Хотя в этом нет необходимости, но вы можете быть более точны при использовании приведения, которое имеет тот же эффект, что и вызов toString():

System.out.println((String)e.next());

Однако в общем случае вы захотите сделать что-то большее, нежели вызов методов Object, так что вы вновь будете применять приведение типов. Вы должны принимать во внимание, что вам интереснее получить Iterator для последовательности определенного типа и приводить результирующие объекты к этому типу (если вы ошиблись, получите исключение времени выполнения).




Дата добавления: 2015-09-11; просмотров: 77 | Поможем написать вашу работу | Нарушение авторских прав

Массивы | Массивы - первоклассные объекты | Возвращение массива | Класс Arrays | Сравнение элементов массива | Сортировка массива | Поиск в отсортированном массиве | Введение в контейнеры | Распечатка контейнера | Заполнение контейнеров |


lektsii.net - Лекции.Нет - 2014-2025 год. (0.009 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав