Абстрактный класс AbstractList реализует интерфейс List, но оставляет нереализованным метод get() и унаследованный метод size() Этот класс позволяет реализовать коллекцию спрямым доступом к элементам, подобно массиву
Абстрактный класс AbstractSequentialList реализует интерфейс List, но оставляет нереализованным метод listiterator(int index) и унаследованный метод size(). Данный класс позволяет реализовать коллекции с последовательным доступом к элементам с помощью итератора Listiterator
Абстрактный класс AbstractSet реализует интерфейс Set, но оставляет нереализованными методы, унаследованные от AbstractCollection
Абстрактный класс AbstractMap реализует интерфейс Map, но оставляет нереализованным метод entrySet (),
Наконец, в составе Java API есть полностью реализованные классы-коллекции помимо уже рассмотренных классов Vector, Stack,Hashtable и Properties, Это классы ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap, WeakHashMap ,
Для работы с этими классами разработаны интерфейсы Iterator,
Listiterator, Comparator ИклассыArrays И Collections.
Перед тем как рассмотреть использование данных классов, обсудим понятие итератора.
В 90-х годах было решено заносить данные в определенную коллекцию, скрыв ее внутреннюю структуру, а для работы с данными использовать методы этой коллекции.
В частности, задачу обхода возложили на саму коллекцию. В Java API введен интерфейс Iterator, описывающий способ обхода всех элементов коллекции. В каждой коллекции есть метод iterator(), возвращающий реализацию интерфейса Iterator для указанной коллекции. Получив эту реализацию, можно обходить коллекцию в некотором порядке, определенном данным итератором, с помощью методов, описанных в интерфейсе Iterator и реализованных в этом итераторе. Подобная техника использована в классе StringTokenizer.
В интерфейсе Iterator описаны всего три метода:
o логический метод hasNext () возвращает true, если обход еще не завершен;
o метод next() делает текущим следующий элемент коллекции и возвращает его в виде объекта класса Object;
o метод remove() удаляет текущий элемент коллекции.
Можно представить себе дело так, что итератор — это указатель на элемент коллекции. При создании итератора указатель устанавливается перед первым элементом, метод next() перемещает указатель на первый элемент и показывает его. Следующее применение метода next() перемещает указатель на второй элемент коллекции и показывает его. Последнее применение метода next() выводит указатель за последний элемент коллекции.
Метод remove(), пожалуй, излишен, он уже не относится к задаче обхода коллекции, но позволяет при просмотре коллекции удалять из нее ненужные элементы.
Пример. Использование итератора вектора
Vector v = new Vector();
String s = "Строка, которую мы хотим разобрать на слова.";
StringTokenizer st = new StringTokenizer(s, " \t\n\r,.");
while (st.hasMoreTokens()){
// Получаем слово и заносим в вектор.
v.add(st.nextToken()); // Добавляем в конец вектора }
System.out.print*Ln(v.firstElement(}); // Первыйэлемент
System.out.println(v.lastElement()); // Последнийэлемент
v.SetSize(4); // Уменьшаем число элементов
v.add("собрать."); // Добавляем в конец укороченного вектора
v.Set(3, "опять"); // Ставим в позицию 3
for (int i = 0; i < v.sizeO; i++) // Перебираемвесьвектор
System.out.print(v.get(i) + ".");
System.out.println(};
Iterator it = v.Iterator (); // Получаемитераторвектора
try{
while(it.hasNext()) // Пока в векторе есть элементы,
System.out.println(it.next()); // выводим текущий элемент
}catch(Exception e){}
Интерфейс ListIterator расширяет интерфейс Iterator, обеспечивая перемещение по коллекции как в прямом, так и в обратном направлении. Он может быть реализован только в тех коллекциях, в которых есть понятия следующего и предыдущего элемента и где элементы пронумерованы.
В интерфейс ListIterator добавлены следующие методы:
void add (Object element) — добавляет элемент element перед текущим элементом;
boolean hasPrevious() — возвращает true, если в коллекции есть элементы, стоящие перед текущим элементом;
int nextindex() — возвращает индекс текущего элемента; если текущим является последний элемент коллекции, возвращает размер коллекции;
Object previous() — возвращает предыдущий элемент и делает его текущим;
int previous index() — возвращает индекс предыдущего элемента;
void Set (Object element)— заменяет текущий элемент элементом element;
выполняется сразу после next() или previous().
Как видите, итераторы могут изменять коллекцию, в которой они работают, добавляя, удаляя и заменяя элементы. Чтобы это не приводило к конфликтам, предусмотрена исключительная ситуация, возникающая при попытке использования итераторов параллельно "родным" методам коллекции. Именно поэтому в следующем примере действия с итератором заключены в блок try(){}— catch(){}.
Пример с использованием итератора ListIterator.
Vector v = new Vector();
String s = "Строка, которую мы хотим разобрать на слова.";
StringTokenizer st = new StringTokenizer(s, " \t\n\r,.");
while (st.hasMoreTokens()){
// Получаем слово и заносим в вектор
v.add(st.nextToken()); // Добавляем в конец вектора
}
ListIterator lit = v.listlterator(); // Получаемитераторвектора
// Указатель сейчас находится перед началом вектора
try{
while(lit.hasNext()) // Пока в векторе есть элементы
System.out.println(lit.next()); // Переходим к следующему
// элементу и выводим его
// Теперь указатель за концом вектора. Пройдемкначалу
while (lit.hasPrevious())System.out.println(lit.previous());
}
catch (Exceptione) {}
Посмотрим теперь, какие возможности предоставляют классы-коллекции Java2.
Класс ArrayList полностью реализует интерфейс List и итератор типа Iterator. Класс ArrayList очень похож на класс Vector, имеет тот же набор методов и может использоваться в тех же ситуациях.
В классе ArrayList три конструктора;
ArrayList()— создает пустой объект;
ArrayList(Collection coll) — создает объект, содержащий все элементы коллекции coll;
ArrayList (int initCapacity) — создаетпустойОбъектемкостиinitCapacity.
Единственное отличие класса ArrayList от класса Vector заключается в том, что класс ArrayList не синхронизован. Это означает что одновременное изменение экземпляра этого класса несколькими подпроцессами приведет к непредсказуемым результатам.
Интерфейс Comparator описывает два метода сравнения:
int compare (Object obji, Object obj2) — возвращает отрицательное число, если obj1 в каком-то смысле меньше obj2; нуль, если они считаются равными; положительное число, если obj1 больше obj2. Этот метод сравнения обладает свойствами тождества, антисимметричности и транзитивности;
boolean equals (Object obj) — сравнивает данный объект с объектом obj, возвращая true, если объекты совпадают в каком-либо смысле, заданном этим методом.
Для каждой коллекции можно реализовать эти два метода, задав конкретный способ сравнения элементов, и определить объект класса SortedMap вторым конструктором. Элементы коллекции будут автоматически отсортированы в заданном порядке.
Класс HashSet полностью реализует интерфейс Set и итератор типа Iterator. Класс HashSet используется в тех случаях, когда надо хранить только одну копию каждого элемента.
В классе HashSet четыре конструктора:
HashSet() — создает пустой объект с показателем загруженности 0,75;
HashSet (int capacity) — создает пустой объект с начальной емкостью capacity и показателем загруженности 0,75;
HashSet (int capacity, float loadFactor) — создает пустой объект с начальной емкостью capacity и показателем загруженности loadFactor;
HashSet (Collection coll) — создает объект, содержащий все элементы коллекции coll, с емкостью, равной удвоенному числу элементов коллекции coll, но не менее 11, и показателем загруженности 0,75.
Класс TreeSet полностью реализует интерфейс SortedSet и итератор типа Iterator. Класс TreeSet реализован как бинарное дерево поиска, значит, его элементы хранятся в упорядоченном виде. Это значительно ускоряет поиск нужного элемента.
Порядок задается либо естественным следованием элементов, либо объектом, реализующим интерфейс сравнения Comparator.
Этот класс удобен при поиске элемента во множестве, например, для проверки, обладает ли какой-либо элемент свойством, определяющим множество.
В классе TreeSet четыре конструктора:
TreeSet() — создает пустой объект с естественным порядком элементов;
TreeSet (Comparator с) — создает пустой объект, в котором порядок задается объектом сравнения с;
TreeSet (Collection coll) — создает объект, содержащий все элементы коллекции coll, с естественным порядком ее элементов;
TreeSet (SortedMap sf) — создает объект, содержащий все элементы отображения sf, в том же порядке.
Коллекции предназначены для хранения элементов в удобном для дальнейшей обработки виде. Очень часто обработка заключается в сортировке элементов и поиске нужного элемента. Эти и другие методы обработки собраны в класс Collections.
Все методы класса Collections статические, ими можно пользоваться, не создавая экземпляры классу Collections
Как обычно в статических методах, коллекция, с которой работает метод, задается его аргументом.
Сортировка может быть сделана только в упорядочиваемой коллекции, реализующей интерфейс List. Для сортировки в классе Collections есть два метода:
static void sort (List coll) — сортирует в естественном порядке возрастания коллекцию coll, реализующую интерфейс List;
static void sort (List coll, Comparator c) — сортируетколлекциюcoll
в порядке, заданном объектом с. После сортировки можно осуществить бинарный поиск в коллекции:
static int binarySearch(List coll, Object element) — отыскивает элементelement в отсортированной в естественном порядке возрастания коллекции coll и возвращает индекс элемента или отрицательное число, если элемент не найден; отрицательное число показывает индекс, с которым элемент element был бы вставлен в коллекцию, с обратным знаком;
static int binarySearchfList coll, Object element, Comparator c) — то же, но коллекция отсортирована в порядке, определенном объектом с.
Четыре метода находят наибольший и наименьший элементы в упорядочиваемой коллекции:
static Object max (Collection coll) — возвращает наибольший в естественном порядке элемент коллекции coll;