Философия Java


Cборщики и итераторы - часть 2


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

Решением этого является итератор, который является объектом, чья работа - это выбор элементов из контейнера и представление их пользователю итератора. Как класс, он также обеспечивает уровень абстракции. Эта абстракция может быть использована для разделения деталей контейнера от кода, который имеет доступ к контейнеру. Контейнер через итератор абстрагируется до простой последовательности. Итератор позволяет вам обработать эту последовательность, не заботясь о лежащей в основе структуре — является ли она ArrayList, LinkedList, Stack или чем-то еще. Это дает вам гибкость для легкой смены лежащей в основе структуры данных без переделки кода вашей программы. Java началась (в версиях 1.0 и 1.1) со стандартного итератора, называемого Enumeration, для всех контейнерных классов. В Java 2 добавлено много более сложных библиотек контейнеров, которые содержат итераторы, называемые Iterator, который делает много больше, чем старый Enumeration.

С точки зрения разработки, все что вам нужно - это последовательность, которой можно манипулировать для решения вашей проблемы. Если последовательность простых типов удовлетворяет всем вашим требованиям, то нет смысла иметь другие типы. Есть два довода, почему вам необходимы контейнеры. Во-первых, контейнеры обеспечивают различные типы интерфейсов и внешних воздействий. Стек имеет различные интерфейсы и поведение, в отличие от очереди, которая отличается от набора или списка. Один из них может обеспечивать более гибкое решение вашей проблемы, чем другие. Во-вторых, различные контейнеры имеют различную эффективность для определенных операций. Лучший пример - это ArrayList и LinkedList. Оба контейнера - это простая последовательность, которые могут иметь одинаковые интерфейсы и внешнее поведение. Но определенные операции могут иметь радикальное отличие в стоимости. Случайный доступ к элементам в ArrayList - это операция постоянная по времени. Она занимает примерно одно и то же время не зависимо от выбираемого вами элемента. Однако в LinkedList очень дорого перемещаться по списку элементов в случайном порядке, и занимает больше времени при нахождении элемента, чем при переборе их вниз по списку. С другой стороны, если вы хотите вставить элемент в середину последовательности, это дешевле в LinkedList, чем в ArrayList. Есть и другие операции, имеющие различия в эффективности, в зависимости от лежащей в основе структуры последовательности. В фазе разработки вы можете начать с LinkedList и, когда будете настраивать производительность, сменить на ArrayList. Поскольку есть абстракция через итераторы, вы можете сменить один на другой с минимальной переработкой вашего кода.

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




Начало  Назад  Вперед



Книжный магазин