410013796724260
• Webmoney
R335386147728
Z369087728698
Наборы данных CollectionВ парадигме объектно-ориентированного программирования поддерживается концепция инкапсуляции данных внутри классов. Однако это не означает, что способы размещения данных играют менее важную роль. Конечно же, используемая структура данных зависит от решаемой задачи. Способ организации данных внутри класса имеет очень важное значение для реализации методов и достижения максимальной производительности. Интерфейс Collection является фундаментальным интерфейсом для классов Java, поддерживающих наборы данных (коллекции), в котором объявлены следующие 2 основных метода : public interface Collection<E> { boolean add (E element(); Iterator <E> iterator(); } Помимо них, интерфейс Collection имеет еще несколько методов, которые рассмотрены ниже. Метод add() добавляет элемент к набору и возвращает либо значение true, если набор данных изменился, либо false в противном случае. Например, если попытаться добавить в множество уже существующий объект, то запрос add() будет проигнорирован, поскольку по определению множество не может содержать дублирующие объекты. Метод iterator() возвращает объект-итератор, реализующий интерфейс Iterator, который используется для последовательного обращения к элементам набора данных. Интерфейс IteratorВ интерфейсе Iterator определены следующие три основных метода: public interface Iterator<E> { E next; boolean hasNext(); void remove(); } Реализация интерфейса Iterator предполагает, что с помощью вызова метода next() можно получить следующий элемент. С помощью метода hasNext() можно узнать, есть ли следующий элемент, и не достигнут ли конец коллекции. И если элементы еще имеются, то hasNext() вернет значение true. Метод hasNext() следует вызывать перед методом next(), так как при достижении конца коллекции метод next() выбрасывает исключение NoSuchElementException. И метод remove() удаляет текущий элемент, который был получен последним вызовом next(). Пример с Iterator для перебора коллекции, метод hasNextimport java.util.*; public class CollectionApp { public static void main(String[] args) { List<String> states = new ArrayList<String>(); states.add("Германия"); states.add("Франция"); states.add("Италия"); states.add("Испания"); Iterator<String> iter = states.iterator(); while(iter.hasNext()){ System.out.println(iter.next()); } } } Цикл for eachНачиная с JDK 5.0 можно сократить запись цикла, используя выражение "for each" for (String element : list) { System.out.println(element.toString()); } Компилятор преобразует цикл "for each" в обычный цикл с итератором. Цикл "for each" работает с любым объектом, реализующим интерфейс Iterable, в котором объявлен единственный метод public interface Iterable <E> { Iterator <E> iterator(); } Интерфейс Collection расширяет интерфейс Iterable. Поэтому цикл "for each" можно использовать для любого набора данных из стандартной библиотеки. Порядок следования элементов в итератореПорядок перебора элементов коллекции зависит от типа и набора элементов. Если используется объект ArrayList, то итератор начинает с индекса 0 и увеличивает индекс на 1 на каждом шаге. Если объект имеет тип HashSet, то порядок следования элементов коллекции может оказаться случайным. При использовании итератора Iterator, можно быть уверенным, что он переберет все элементы, но строить предположения о порядке, в котором элементы будут извлекаться, по меньшей мере рискованно. В большинстве случаев порядок следования элементов не имеет никакого значения. Удаление элементов итераторомМетод remove() интерфейса Iterable удаляет элемент, возвращенный в результате последнего вызова метода next(). В большистве случаев это правильно, т.к. необходимо проверить элемент перед принятием решения об его удалении. Пример удаления первого элемента набора строк с использованием итератора : Iterator it = states.iterator(); it.next(); it.remove(); Необходимо помнить, что перед вызовом next() и удалением remove() существует строгая взаимосвязь. Нельзя вызывать метод remove(), если ему не предшествовал вызов метода next(). При попытке сделать это будет сгенерировано исключение IllegalStateException. При необходимости удаления двух соседних элементов нельзя дважды подряд вызвать метод remove(). it.remove(); it.remove(); // Ошибка Нужно сначала вызвать метод next(), чтобы итератор (указатель) встал на элемент, подлежащий удалению. it.remove(); it.next(); it.remove(); // Правильно Универсальные вспомогательные методы, containsИнтерфейсы Collection и Iterable являются универсальными, поэтому для них можно создавать универсальные методы, работающие для любых наборов данных. Пример универсального метода contains, проверяющего наличие элемента obj в наборе данных : public static <E> boolean contains ( Collection <E> c, Object obj) { for (E element : c) if (element.equals(obj)) return true; return false; } it.next(); it.remove(); // Правильно Разработчики библиотеки Java добавили ряд полезных методов в интерфейс Collection, которые должны поддерживаться во всех реализующих его классах:
Применение каждым классом, реализующим интерфейс Collection, такого количества стандартных методов было бы слишком обременительным. Чтобы упростить процесс их реализации, в классе AbstractCollection оставлены абстрактными только фундаментальные методы (такие, как size() и iterator()), а на их основе реализованы все остальные стандартные методы. public abstract class AbstractCollection <E> implements Collection <E> { . . . public abstract Iterator <E> iterator(); public boolean contains (Object obj) { for (E element : c) // Вызов метода iterator() if (element.equals(obj)) return true; return false; } . . . } Теперь конкретный класс, представляющий набор данных, может расширить класс AbstractCollection за счет реализации метода iterator(), а метод contains() уже реализован в родительском классе AbstractCollection. Однако, если дочерний класс содержит более эффективный вариант реализации метода contains(), то его можно использовать вместо варианта родительского класса. Методы интерфейса java.util.Collection<E>
Методы итератора java.util.Iterator<E>
Интерфейс ListIteratorИнтерфейс Iterator предоставляет ограниченный функционал. Гораздо больший набор методов предоставляет другой итератор - интерфейс ListIterator. Данный итератор используется классами, реализующими интерфейс List, то есть классами LinkedList, ArrayList и др. Интерфейс ListIterator расширяет интерфейс Iterator и определяет ряд дополнительных методов:
Пример использования итератора ListIteratorimport java.util.*; public class CollectionApp { public static void main(String[] args) { ArrayList<String> states; states = new ArrayList<String>(); states.add("Германия"); states.add("Франция"); states.add("Италия"); states.add("Испания"); ListIterator<String> listIter; listIter = states.listIterator(); while(listIter.hasNext()){ System.out.println(listIter.next()); } // Текущим элементом является строка Испания // Изменение значения этого элемента listIter.set("Португалия"); // Перебор элементов в обратном порядке while(listIter.hasPrevious()){ System.out.println(listIter.previous()); } } } Иерархия наборов данных интерфейса CollectionНа рисунке представлена иерархия наборов классов, реализующих интерфейс Collection: Список наборов данныхВ таблице представлен список наборов данных. Все классы с именами, оканчивающимися на Map реализуют интерфейс Map, остальные интерфейс Collection.
|