Главная страница

Java. Полное руководство. 8-е издание. С. Н. Тригуб Перевод с английского и редакция


Скачать 25.04 Mb.
НазваниеС. Н. Тригуб Перевод с английского и редакция
АнкорJava. Полное руководство. 8-е издание.pdf
Дата28.02.2017
Размер25.04 Mb.
Формат файлаpdf
Имя файлаJava. Полное руководство. 8-е издание.pdf
ТипДокументы
#3236
страница40 из 90
1   ...   36   37   38   39   40   41   42   43   ...   90
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
4 8 Класс
A r r a y L i s Класс
ArrayList расширяет класс
AbstractList и реализует интерфейс
List. Класс
ArrayList
— это обобщенный класс со следующим объявлением Здесь параметр Е указывает тип сохраняемых объектов.
Класс
ArrayList поддерживает динамические массивы, которые могут расти по мере необходимости. Стандартные массивы Java имеют фиксированную длину. После того как массив создан, он не может увеличиваться или уменьшаться, а это значит, что следует заранее знать, сколько элементов нужно в нем хранить. Но иногда вы не можете точно знать до момента выполнения программы, насколько большой массив понадобится. Чтобы справиться с этой ситуацией, в инфраструктуре коллекций определен класс
ArrayList. По сути, класс
ArrayList
— это массив объектных ссылок переменной длины. То есть объект класса
ArrayList может динамически увеличиваться или уменьшаться в размере. Массивы-списки
(ArrayList) создаются с некоторым начальным размером. Когда этот первоначальный размер становится недостаточным, коллекция автоматически увеличивается. Когда объекты удаляются, коллекция может уменьшаться.
На заметку Динамические массивы поддерживаются также унаследованным классом
Vector, который будет описан далее в главе.

Класс
ArrayList имеет следующие конструкторы с

емкость)
Первый конструктор создает пустой массив-список. Второй создает массив- список, который инициализируется элементами коллекции с. Третий конструктор создает массив-список, который имеет начальную емкость емкость Емкость — это размер лежащего в основе массива, используемого для хранения элементов. Емкость растет автоматически по мере добавления элементов в массив-список.
В следующей программе демонстрируется простое применение класса
ArrayList. Создается массив-список для объектов класса
String, затем в него добавляется несколько строк. (Вспомните, что строки в кавычках транслируются в объекты класса
String.) После этого отображается список. Некоторые элементы удаляются, и список отображается снова Демонстрация использования ArrayList.
import java.util.*?
class ArrayListDemo {
public static void main (String a r g s []) {
// Создать массив-список.
ArrayList al = new Начальный размер al: " + al.sizeO);

4 8 Часть II. Библиотека Java
// Добавить элементы в массив-список.
a l .a d d (С l .a d d (А " );
a l .a d d ("E");
a l .a d d ("B");
a l .a d d ("D");
a l .a d d ("F");
a l .a d d (1, "Размер al после вставки " +
a l .s i z e ());
// отобразить массив-список.
System.out.println("Содержимое a l :
" + al);
// Удалить элементы из массива-списка,
a l .remove("F");
a l Размер al после удалений: " + al.sizeO); Содержимое a l :
" + al) Вывод программы показан ниже.
Начальный размер a l :
О Размер al после вставки 7 Содержимое al: С, А 2 ,

А, Е, В, D ,
Размер al после удалений: 5 Содержимое al: С, А, Е, В, Обратите внимание на то, что массив-список а 1 изначально пусти растет по мере добавления в него элементов. Когда элементы удаляются, его размер уменьшается.
В предыдущем примере содержимое коллекции отображается с использованием преобразования типов по умолчанию, предоставляемого методом t o S t r i n g (), который унаследован от класса Abs t r a c t Со 11 e c t io n . Несмотря на то что это удобно при написании коротких примеров программ, вы редко будете пользоваться этим методом для отображения содержимого реальных коллекций. Обычно выбудете пред- сматривать свои собственные процедуры вывода. Но для нескольких следующих примеров вывод по умолчанию, выполняемый методом t o S t r i n g (), вполне подойдет.
Невзирая на то что емкость объектов класса A r r a y L i s t растет автоматически, по мере сохранения в них объектов, вы также можете увеличивать эту емкость вручную, вызывая метод e n s u r e C a p a c i t y (). Это может потребоваться, если вы заранее знаете, что собираетесь сохранить в коллекции намного больше элементов, чем она содержит в данный момент. Увеличивая емкость однажды, вначале работы, вы тем самым предотвращаете несколько дополнительных распределений памяти позднее. Поскольку перераспределения памяти — дорогостоящие операции в смысле временных затрат, предотвращение таких излишних операций увеличивает производительность. Сигнатура метода e n s u r e C a p a c i t y () показана ниже,
void ensureCapacity(int
емкость)
Здесь емкость задает новую минимальную емкость коллекции.
И наоборот, когда вы хотите уменьшить размер массива объектов, лежащего в основе объекта класса A r r a y L i s t , до текущего реального количества хранимых объектов, вызовите метод t r i m T o S i z e ().
void trimToSize()
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
4 8 Получение массива из объекта класса A r r a y L i s При работе с классом
A r r a y L i s t иногда необходимо получить обыкновенный массив, содержащий все элементы списка. Это можно сделать, вызвав метод t o A r r a y ( )
, который определен в интерфейсе
C o l l e c t i o n Существует несколько причин, по которым вам может понадобиться преобразовать коллекцию в массив.
• Для ускорения выполнения некоторых операций.
• Для передачи массива в качестве параметра методам, не перегруженным для непосредственного использования коллекций.
• Для интеграции нового кода, основанного на коллекциях с унаследованным кодом, который не понимает коллекций.
Независимо от причины, преобразование объекта класса
A r r a y L i s t в массив — задача тривиальная.
Как объяснялось ранее, существует две версии метода t оА ггау ( ), которые показаны ниже b j e c t [] Т Т toArray

( Т массив Первая версия возвращает массив объектов класса
Obj e c t , вторая — массив элементов, имеющих тип Т Обычно вторая форма удобнее, поскольку возвращает правильный тип массива. В следующей программе демонстрируется их применение Преобразование ArrayList в массив
import java.util.*;
class ArrayListToArray {
public static void main(String a r g s []) {
11
Создать массив-список.
ArrayList al = new ArrayList();
11
Добавить элементы в массив-список,
a l .a d d (1);
a l .a d d (2);
a l .a d d (3);
a l .a d d (4) Содержимое a l :
" + al);
// Получить массив ia[] = new Integer[al.s i z e ()];
ia = a l .toArray(ia);
int sum = 0;
// Суммировать массив
for(int i :
ia) sum +
= Сумма " + Вывод программы будет выглядеть так.
Содержимое a l :
[1, 2, 3, Сумма О

4 9 Часть II. Библиотека Программа начинается с создания коллекции целых чисел. Затем вызывается метод toArray
( ), и получается массив элементов класса
Integer. Далее содержимое массива суммируется в цикле for вида Есть еще кое-что интересное в этой программе. Как вызнаете, коллекции могут содержать только ссылки, а не значения элементарных типов. Однако автоматическая упаковка позволяет передавать методу add
() значения типа int, без необходимости помещать их в оболочку
Integer, как это демонстрируется в программе. Это осуществляет автоматическая упаковка. Таким образом, она ощутимо облегчает сохранение в коллекциях значений элементарных типов.
Класс
L i n k e d L i s Этот класс расширяет класс
AbstractSequentalList и реализует интерфейсы и
Queue. Он представляет структуру данных связного списка. Класс
LinkedList
— это обобщенный класс со следующим объявлением Здесь
Е
указывает тип сохраняемых в списке объектов. Класс
LinkedList имеет следующие два конструктора extends

E> с)
Первый конструктор создает пустой связный список. Второй — создает связный список и инициирует его содержимым коллекции с.
Поскольку класс
LinkedList реализует интерфейс
Deque, вы имеете доступ к методам, определенным в интерфейсе
Deque. Например, чтобы добавить элементы в начало списка, вы можете использовать методы addFirst (
) или of ferFirst (). Для добавления элементов вконец списка применяйте методы addLast
() или of
- ferLast
(). Чтобы получить первый элемент, используйте методы getLast
() или peekLast
(). Чтобы удалить первый элемент, вызывайте методы removeFirst
() или pollFirst(). Для удаления последнего элемента используются методы ге- moveLast () HumpollLast (В следующей программе иллюстрируется использование класса
LinkedList.
// Демонстрация применения LinkedList.
import java.util.*;
class LinkedListDemo {
public static void main(String a r g s []) {
// Создать связный список 11 = new LinkedList();
// Добавить элементы в связный список d d ("F ")
11.a d d (В ")
11.a d d ("D ")
11.a d d ("E ")
11.a d d (С ")
11.addLast(
11.addFirst(
"A");
11.a d d (1, "A 2 "Исходное содержимое 11: " + 11);
// Удалить элементы из связного списка
11.remove("F ");
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
4 9 Содержимое 11 после удаления " + 11);
// Удалить первый и последний элементы после удаления первого и последнего " +
1 1 )
;
// Получить и присвоить значение val = 11.g e t (2);
11.s e t (2, val + " Изменен после изменения " + Ниже показан вывод этой программы.
Исходное содержимое 11: А, А ,
F, ВЕС Содержимое 11 после удаления А, А ,
D, Е, С Z]
11 после удаления первого и последнего А ,
D, Е С после изменения А D, Е Changed, С]
Поскольку класс
LinkedList реализует интерфейс
List, вызов метода add (Е) добавляет элементы вконец списка, как это делает и метод addLast
(). Чтобы вставить элементы в определенное место, используйте форму add
(
int
, Е, как демонстрирует в примере вызов метода add
( 1
,
" АО братите внимание на то, как изменяется третий элемент в связном списке 11 с помощью методов get (
) и set ()
. Чтобы получить текущее значение элемента, методу get
() передается индекс позиции, в которой расположен элемент. Чтобы присвоить новое значение элементу в этой позиции, методу set
() передается соответствующий индекс и новое значение.
Класс
H a s h S e Класс
HashSet расширяет класс
AbstractSet и реализует интерфейс
Set. Он создает коллекцию, которая использует для хранения хеш-таблицу. Класс
HashSet
— это обобщенный класс, имеющий следующее объявление Здесь Е указывает тип объектов, которые будут храниться в наборе.
Как большинство читателей, вероятно, знают, хеш-таблица хранит информацию, используя так называемый механизм хеширования, в котором содержимое ключа используется для определения уникального значения, называемого хеш- кодом Этот хеш-код затем применяется в качестве индекса, с которым ассоциируются данные, доступные поэтому ключу. Преобразование ключа в хеш-код выполняется автоматически — вы никогда не увидите самого хеш-кода. Также ваш код не может напрямую индексировать хеш-таблицу. Выгода от хеширования состоит в том, что оно обеспечивает константное время выполнения методов add
( ), con­
tains ()
, remove () и size ()
, даже для больших наборов.
Определены следующие конструкторы extends E> с емкость емкость float

коэффЗаполнения)
Д 9 Часть II. Библиотека Первая форма конструктора создает хеш-набор по умолчанию. Вторая форма инициирует его содержимым коллекции с. Третья форма устанавливает емкость хеш-набора равной емкость (Емкость по умолчанию — 16.) Четвертая форма инициирует и емкость, и коэффициент заполнения (fill ratio), называемый также емкостью загрузки (load capacity) из аргументов конструктора. Коэффициент заполнения должен быть в пределах от 0,0 дои это определяет, насколько заполненным должен быть хеш-набор, прежде чем будет выполнено изменение его размера. Точнее говоря, когда количество элементов становится больше емкости хеш-набора, умноженной на коэффициент заполнения, такой хеш-набор увеличивается. В конструкторах, которые не принимают параметр коэффициента заполнения, принимается значение Класс
HashSet не определяет никаких дополнительных методов, помимо представленных его суперклассами и интерфейсами.
Важно отметить, что класс
HashSet не гарантирует упорядоченности элементов, поскольку процесс хеширования сам по себе обычно не порождает сортированных наборов. Если вам нужны сортированные наборы, то лучшим выбором может быть другой тип коллекций, такой как класс Ниже показан пример применения класса
HashSet.
// Демонстрация применения HashSet.
import java.util.*;
class HashSetDemo {
public static void main(String a r g s []) {
// Создать хеш-набор.
HashSet hs = new HashSet();
// Добавить элементы в хеш-набор.
h s .a d d (В s .a d d ("A");
h s .a d d ("D");
h s .a d d ("E ");
h s .a d d (С ");
h s .a d d (Вывод этой программы выглядит следующим образом Е ,
F ,
А, В, С]
Как объяснялось, элементы не сохраняются в отсортированном порядке, поэтому порядок их вывода может варьироваться.
Класс
L i n k e d H a s h S e Класс
LinkedHashSet расширяет класс
HashSet, не добавляя никаких новых методов. Это обобщенный класс со следующим объявлением Здесь Е указывает тип объектов, которые будут храниться в наборе. Конструкторы этого класса аналогичны конструкторам класса Класс
LinkedHashSet поддерживает связный список элементов набора в том порядке, в котором они вставлялись. Это позволяет организовать упорядоченную итерацию вставки в набор. То есть, когда идет перебор объекта класса
LinkedHashSet с применением итератора, элементы извлекаются в том порядке, в каком они были
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
4 9 вставлены. Это также тот порядок, в котором они будут возвращены методом to­
String
() объекта класса
LinkedHashSet. Чтобы увидеть эффект от применения класса
LinkedHashSet, попробуйте подставить его в предыдущем примере вместо класса
HashSet. Вывод программы после этого будет выглядеть так.
[В, A, D ,
Е, С, F Это отражает порядок, в каком элементы вставлялись в набор.
Класс
T r e e S e Класс
TreeSet расширяет класс
AbstractSet и реализует интерфейс
NavigableSet. Он создает коллекцию, которая для хранения элементов применяет дерево. Объекты сохраняются в отсортированном порядке по возрастанию. Время доступа и извлечения элементов достаточно мало, что делает класс
TreeSet блестящим выбором для хранения больших объемов отсортированной информации, которая должна быть быстро найдена. Класс
TreeSet
— это обобщенный класс со следующим объявлением,
class Здесь Е указывает тип объектов, которые будут храниться в наборе.
Класс
TreeSet имеет следующие конструкторы extends

E> с )
TreeSet(Comparator
E> компаратор Первая форма создает пустой набор-дерево, который будет сортировать элементы в естественном порядке возрастания. Вторая форма создает набор-дерево, содержащий элементы коллекции с. Третья форма создает пустой набор-дерево, элементы в котором будут отсортированы компаратором, указанным в параметре компаратор (Компараторы рассматриваются далее в настоящей главе) Четвертая форма создает набор-дерево, содержащий элементы из s s . Ниже показан пример использования класса
TreeSet.
/ Демонстрация TreeSet.
import java.util.*;
class TreeSetDemo {
public static void main(String a r g s []) {
// Создать TreeSet.
TreeSet ts = new TreeSet();
// Добавить элементы в TreeSet.
t
s .a d d (С ") ;
t
s .a d d ("A");
t s .a d d ("B");
t s .a d d ("E");
t
s .a d d ("F ");
t s .a d d (Вот как выглядит вывод этой программы.
[А, ВСЕ Часть II. Библиотека Как уже объяснялось, поскольку класс
TreeSet сохраняет элементы дерева, они автоматически располагаются в отсортированном порядке, что и подтверждает вывод программы.
Поскольку класс
TreeSet реализует интерфейс
NavigableSet добавленный в Java SE 6), вы можете использовать методы, определенные в интерфейсе
NavigableSet, для извлечения элементов класса
TreeSet. Например, предположим, что в предыдущую программу был добавлен следующий оператор, который использует метод subset
() для получения набора t s, содержащего элементы между С включительно) и
F исключительно. Затем отображается результирующий набор.
System.out.println(ts.subset("С",
"F "Вывод этого оператора показан ниже.
[С, D, Е]
П ри желании вы можете поэкспериментировать с другими методами, определенными в интерфейсе Класс

P r i o r i t y Q u e u Класс
PriorityQueue расширяет класс
Abs tract
Queue и реализует интерфейс
Queue. Он создает очередь с приоритетами на базе компаратора очереди. Класс
PriorityQueue является обобщенным классом со следующим объявлением Здесь Е указывает тип объектов, которые будут храниться в очереди. Объект класса
PriorityQueue является динамической коллекцией и при необходимости может увеличиваться.
Класс
PriorityQueue определяет шесть конструкторов емкость емкость Comparator
E> компаратор extends

E> c)
PriorityQueue(PriorityQueue
E> c)
PriorityQueue(SortedSet
E> Первый конструктор создает пустую очередь. Его начальная емкость равна 11. Второй конструктор создает очередь с заданной начальной емкостью. Третий конструктор создает очередь заданной емкости с заданным компаратором. Последние три конструктора создают очереди, инициированные элементами коллекций, переданных в параметре с. Во всех случаях по мере добавления элементов емкость автоматически растет.
Если при создании объекта класса
PriorityQueue никакой компаратор не указан, то применяется стандартный компаратор для того типа данных, который сохраняется в очереди. Стандартный компаратор размещает элементы очереди в порядке возрастания. Таким образом, вначале (голове) очереди будет находиться наименьшее значение. Однако, предоставляя собственный компаратор, вы можете задать другую схему сортировки элементов. Например, когда сохраняются элементы, включающие временную метку, вы можете ввести приоритеты в очередь таким образом, чтобы самые старые элементы располагались вначале очереди.
Вы можете получить ссылку на компаратор, используемый объектом класса, вызвав его метод comparator ().
Comparator
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
4 9 Возвращает компаратор. Если в данной очереди применяется естественный порядок сортировки, возвращается значение null. Одно предупреждение несмотря на то что вы можете перебрать элементы объекта класса
Priority
Queue, применяя итератор, порядок итерации не определен. Чтобы правильно использовать класс
Priority
Queue, следует вызывать такие методы, как of f er (
) и poll (Класс

A r r a y D e q u Класс
ArrayDeque расширяет класс
AbstractCollection и реализует интерфейс
Deque. Он не добавляет собственных методов. Класс
ArrayDeque создает динамический массив, не имеющий ограничений емкости. (Интерфейс
Deque поддерживает реализации с ограниченной емкостью, ноне накладывает такого ограничения) lOiacc
ArrayDeque
— это обобщенный класс со следующим объявлением,
class A r Здесь Е определяет тип объекта, сохраняемого в коллекции. Класс
ArrayDeque определяет следующие конструкторы r r a y D e q u e ()

A r r a y D e q u e (int размер r a y D e q ue(Collection
E> с Первый конструктор создает пустую двунаправленную очередь. Ее начальная емкость — 16 элементов. Второй конструктор создает двунаправленную очередь с указанной емкостью. Третий конструктор создает двунаправленную очередь, инициализируемую коллекцией, переданной в параметре с. Во всех случаях, по мере необходимости, емкость увеличивается при добавлении новых элементов в двунаправленную очередь.
Приведенная ниже программа демонстрирует применение класса
ArrayDeque для организации стека Демонстрация применения d ma i n ( S t r i n g a r g s []) {

// Создать двухстороннюю очередь u e < S t r i n g > adq = new A r r a y D e q u e < S t r i n g > ();
// Использование A r r ayDeque в виде стека d q . p u s h ("A " );
a d q . p u s h ("B " );
a d q . p u s h ("D " );
a d q . p u s h ("E " );
a d q . p u s h (" F " );
S y s t e m .o u t .p r i n t (Выталкиваем из стека ");
w h i l e ( a d q . p e e k () != null)
S y s t e m . o u t . p r i n t ( a d q . p o p () + " ");
S y s t e m . o u t . p r i n t l n (Вывод этой программы выглядит так.
В ы т алкиваем из стека F ЕВА Часть II. Библиотека Класс
E n u m S e Класс
E num S et расширяет класс
A b s t r a c t S e t и реализует интерфейс
S e t . Он создает коллекцию, которая предназначена для применения с ключами типа enum. Это обобщенный класс со следующим объявлением EnumSetcE extends Здесь E определяет элементы. Отметим, что класс Е должен расширять класса это накладывает требование, что элементы должны относиться копре деленному типу Класс
E num S et не определяет конструкторов. Вместо этого для создания объектов он использует методы фабрики, перечисленные в табл. 17.9. Обратите внимание на то, что метод o f
() перегружен множество раз. Это делается из соображений эффективности. Передача известного количества аргументов может работать быстрее, чем применение параметра с переменным количеством аргументов, когда количество аргументов не велико.
Таблица 17.9. Методы, определенные в классе
E n u m S e Метод Описание Е extends Enum> EnumSet
allOf(Class
t)
static > EnumSet
complementOf(EnumSet e)
static > EnumSet
copyOf(EnumSet c)
static > EnumSet
copyOf(Collection c)
static > EnumSet
noneOf(Class
t)
static > EnumSet
of(E v, E ...
перемколарг)
static >
EnumSet of(E
v)
static > EnumSet
of (E
v l ,
E
v2)
static > EnumSet
of (E
v l ,
E
v 2 ,
E
v3)
static > EnumSet
of (E
v l ,
E
v 2 ,
E
v 3 ,
E
v4)
static > EnumSet
of (E
v l ,
E
v 2 ,
E
v 3 ,
E
v 4 ,
E
v5)
static > EnumSet
range(E начало
конец)
Создает объект класса
EnumSet, который содержит элементы перечисления, указанные в параметре Создает объект класса
EnumSet, который дополняет элементы, отсутствующие в
е
Создает объект класса
EnumSet, содержащий элементы из набора
с
Создает объект класса
EnumSet, содержащий элементы из набора
с
Создает объект класса
EnumSet, содержащий элементы, которые не входят в перечисление, заданное t, которое по определению является пустым набором
Создает объект класса
EnumSet, содержащий элементы
v u
нуль или более дополнительных перечислимых значений
Создает объект класса
EnumSet, содержащий элементы Создает объект класса
EnumSet, содержащий элементы vl и Создает объект класса
EnumSet, содержащий элементы от vl до Создает объект класса
EnumSet, содержащий элементы от vl до Создает объект класса
EnumSet, содержащий элементы от vl до Создает объект класса
EnumSet, содержащий элементы в диапазоне, заданном начало и конец
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
4 9 Доступ к коллекциям через итератор
Зачастую необходимо перебрать все элементы коллекции. Например, необходимо отобразить каждый элемент коллекции. Один из способов сделать это — использовать итератор, представляющий собой объект, реализующий один из двух интерфейсов —
Iterator либо
Listlterator. Интерфейс
Iterator позволяет организовать цикл для перебора коллекции, получая либо удаляя элементы. Интерфейс
Listlterator расширяет интерфейс
Iterator для обеспечения двунаправленного прохода поспи ску и модификации элементов. Интерфейсы
Iterator и
Listlterator
— это обобщенные интерфейсы, объявленные так, как показано ниже Iterator<£>

interface Здесь
E представляет собой тип перебираемых объектов. Интерфейс
Iterator объявляет методы, перечисленные в табл. 17.10. Методы, объявленные винтер фейсе
Listlterator, показаны в табл. Таблица

1 7 .1 0 . Методы, определенные в интерфейсе
i t e r a t o r
Метой
Описание
boolean h a s N e x Возвращает значение
true, если есть еще элементы. В противном случае возвращает значение Е next Возвращает следующий элемент. Передает исключение
NoSuchElementException, если больше нет элементов oid r e m o v Удаляет текущий элемент. Передает исключение
IllegalStateException, если предпринимается попытка вызвать метод
remove
(), которому не предшествовал вызов метода
n e x Таблица 17.11. Методы, определенные в интерфейсе i s t l t e r a t o r
Метод
Описание
void add(E
объект)
Вставляет объект перед элементом, который должен быть возвращен следующим вызовом метода
next
()
boolean h a s N e x Возвращает значение
true, если есть следующий элемент. В противном случае возвращает значение
false
boolean hasPrevious
() Возвращает значение
true, если есть предыдущий элемент. В противном случае возвращает значение
false
E n e x Возвращает следующий элемент. Если следующего нет, передается исключение
NoSuchE
1
ement
Ехсept
i
on
int Возвращает индекс следующего элемента. Если следующего нет, возвращается размер списка p r e v i o u Возвращает предыдущий элемент. Если предыдущего нет, передается исключение
NoSuchElementException
int p r e Возвращает индекс предыдущего элемента. Если предыдущего нет, возвращается значение -1
void r e m o v Удаляет текущий элемент из списка. Если метод
remove
() вызван до метода
next
() или
previous
(), передается исключение
IllegalStateException
void set(E
объект)
Присваивает объект текущему элементу Это элемент, возвращенный последним вызовом метода
next
() или
previous
()

4 9 Часть II. Библиотека В обоих случаях операции, которые модифицируют лежащую в основе коллекцию, необязательны. Например, метод remove
() передаст исключение
UnsupportedOperationException, будучи примененным к коллекции, доступной только для чтения. Возможны также и другие исключения.
Использование интерфейса i t e r a t o Прежде чем обратиться к коллекции через итератор, следует получить его. Каждый класс коллекций предлагает метод iterator
(), который возвращает итератор на начало коллекции. Используя объект итератора, вы можете получить доступ к каждому элементу коллекции — одному за другим. В общем случае, применение итератора для перебора содержимого коллекции сводится к выполнению следующих действий. Установить итератор на начало коллекции, получив его от метода i t er a t or
() коллекции. Организовать цикл, вызывающий метод hasNext
(). Выполнять перебор до тех пор, пока метод hasNext
() возвращает значение true.
3. Внутри цикла получать каждый элемент, вызывая метод next
( Для коллекций, реализующих интерфейс
List, вы также можете получить итератор, вызывая метод listlterator ()
. Как уже объяснялось, итератор списка обеспечивает доступ к элементам коллекции, как в прямом, таки обратном направлении, а также позволяет модифицировать элементы. Во всем остальном интерфейс
Listlterator применяется также, как интерфейс В следующем примере выполняются все перечисленные действия с демонстрацией обоих интерфейсов —
Iterator и
Listlterator. Здесь используется объект класса
ArrayList, но общие принципы применимы к коллекциям любого типа. Конечно, интерфейс
Listlterator доступен только тем коллекциям, которые реализуют интерфейс
List.
// Демонстрация применения итераторов
import java.util.*;
class IteratorDemo {
public static void main(String a r g s []) {
// Создать массив-список.
ArrayList al = new ArrayList();
// Добавить элементы в массив-список.
a l .a d d (С l .a d d ("A " );
a l .a d d ("E ");
a l .a d d ("B");
a l .a d d ("D");
a l .a d d ("F");
// Использовать итераторы для отображения содержимого a l Исходное содержимое al: ");
Iterator itr = a l .iterator();
w h i l e (i t r .hasNext()) {
String element = itr.nextO;
System.out.print(element + " ");
}
System.out.println() ;
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
4 9 9
// Модифицировать текущий объект итерации litr = a l .listIterator();
w h i l e (litr.hasNext()) {
String element = litr.nextO;
litr.set(element +
}
System.out.p r i n t (Модифицированное содержимое a l :
");
itr = a l .iterator();
w h i l e (it r .h a s Next()) {
String element = itr.next();
System.out.print(element + " ");
}
System.out.println();
// Теперь отображаем список в обратном порядке.
System.out.print("Модифицированный список в обратном порядке ");
w h i l e (litr.hasPrevious()) {
String element = litr.previous();
System.out.print(element + " "Ниже показан вывод этой программы.
Исходное содержимое a l :
С А Е В D F Модифицированное содержимое a l :

С+ А+ Е+ В+ D+ Модифицированный список в обратном порядке F+ D+ В+ Е+ А+ С+
Обратите особое внимание на то, как список отображается в обратном порядке. После того как список модифицирован, итератор l i t r указывает наконец списка. Помните, что метод l i t r . h a sN e x t () возвращает значение f a l s e , когда достигнут конец списка) Чтобы перебрать список в обратном порядке, программа продолжает использовать итератор l i t r , нона этот раз она проверяет, существует ли предшествующий элемент. Пока она это делает, извлеченный элемент отображается.
Версия “fo r-e a c h ” цикла
for как альтернатива итераторам
Если вам ненужно модифицировать содержимое коллекции либо извлекать элементы в обратном порядке, в этом случае версия “for-each” цикла f o r может оказаться более удобной альтернативой итераторам. Вспомните, что цикл f o r может перебирать любую коллекцию объектов, реализующую интерфейс I t e r a b l e . Поскольку все классы коллекций реализуют этот интерфейс, ими можно оперировать с помощью цикла f o r В следующем примере цикл f o r используется для суммирования содержимого коллекции Применение цикла "for-each" для перебора элементов коллекции
import java.util.*;
class ForEachDemo {
public static void main(String a r g s []) {
// Создать массив-список для целых чисел vals = new ArrayList();
// Добавить значения в массив-список.

5 0 Часть II. Библиотека Java
v a l s .a d d (1);
v a l s .a d d (2);
v a l s .a d d (3);
v a l s .a d d (4) ;
v a l s .a d d (5) ;
// Использовать цикл для отображения значений.
System.out.print("Исходное содержимое vals: ");
for(int v :
vals)
System.out.print(v + " ");
System.out.println();
// Суммирование значений в цикле for.
int sum = 0;
for(int v :
vals)
sum += Сумма значений " + Вывод этой программы показан ниже.
Исходное содержимое vals: 1 2 3 4 5 Сумма значений Как видите, цикл for существенно проще и короче, чем подход на базе итераторов. Однако он может применяться для построения цикла перебора элементов коллекции только в прямом направлении, ивы не можете модифицировать элементы коллекции.
Использование пользовательских классов в коллекциях
Во всех приведенных ранее примерах в целях простоты в коллекциях сохранялись объекты встроенных классов, таких как
String или
Integer. Конечно, коллекции не ограничиваются сохранением встроенных объектов. Как раз наоборот. Мощность коллекций в том, что они могут хранить любой тип объектов, включая объекты классов, которые создаете вы сами. Например, рассмотрим следующий пример, в котором класс
LinkedList используется для сохранения почтовых адресов Простой пример работы со списком почтовых адресов
import java.util.*;
class Address {
private String name;
private String street;
private String city;
private String state;
private String code;
Address(String n, String s, String c,
String s t ,
String cd) {
name = n ;
street = s;
city = с ;
state = st;
code = cd;
Глава 17. Пакет java.util: инфраструктура Collections Fram ew ork
5 0 1
}
public String toString() {
return name + "\n" + street + "\n"
city + " " + state + " " + code;
}
:lass MailList {
public static void main(String a r g s []) {
LinkedList
ml = new LinkedList
();
// Добавить элементы в связный список
ml.add(new Address("J.W. West", "11 Oak Ave",
"Urbana", "IL", "61801"));
ml.add(new A d dress("Ralph Baker", "1142 Maple Lane"
"Mahomet", "IL", "61853"));
ml.add(new Address("Tom Carlton", "867 Elm St",
"Champaign", "IL", "61820"));
// Отобразить список почтовых адресов
for(Address element :
ml)
System.out.println(element + "\n");
System.out.println() Вывод этой программы приведен ниже. West
11 Oak Ave
Urbana IL 61801
Ralph Baker
1142 Maple Lane
Mahomet IL 618 53
Tom Carlton
867 Elm St
Champaign IL Помимо сохранения пользовательских классов в коллекции, есть еще кое-что, заслуживающее внимания, — эта программа достаточно короткая. Когда вы оцените, что для сохранения, извлечения и обработки почтовых адресов понадобилось всего около 50 строк кода, станет очевидной мощь инфраструктуры коллекций. Как большинство пользователей знают, если все эти функциональные возможности запрограммировать вручную, программа станет в несколько раз длиннее. Коллекции предлагают готовые решения для широкого диапазона программистских задач. Их следует использовать всякий раз, когда ситуация позволяет.
Интерфейс Этот интерфейс не имеет членов. Однако, реализуя его, коллекция сообщает о том, что поддерживает эффективный случайный доступ к своим элементам. Несмотря на то что коллекция может поддерживать случайный доступ, он может быть не слишком эффективным. Проверяя интерфейс
R an do m A ccess, клиентский код может определять вовремя выполнения, допускает ли конкретная коллекция не

5 0 2 Часть II. Библиотека которые типы операций случайного доступа — особенно, насколько они применимы к большим коллекциям. (Вы можете использовать оператор instanceof для определения того, реализует ли класс данный интерфейс) Интерфейс
RandomAccess реализуется классом
ArrayList и, среди прочих, унаследованным классом Работа с картами

Карта (шар) — это объект, который сохраняет ассоциации между ключами и значениями, или пары “ключ-значение”. По заданному ключу вы можете найти его значение. И ключи, и значения являются объектами. Ключи могут быть уникальными, а значения могут дублироваться. Одни карты допускают пустые ключи и пустые значения, другие — нет.
Имеется один ключевой момент относительно карт, который важно упомянуть они не реализуют интерфейс
Iter able. Это означает, что вы не можете перебирать карту, используя форму “for-each” цикла for. Более того, вы не можете получить итератор карты. Однако, как вскоре будет показано, можно получить представление карты в виде коллекции, которое допускает использование и цикла, и итераторов.
Интерфейсы карт
Поскольку интерфейсы карт определяют их характер и природу, обсуждение начнем с них. Интерфейсы, перечисленные в табл. 17.12, поддерживают карты.
Таблица 17.12. Интерфейсы, которые поддерживают карты
Интерфейс
Описание
Мар
Отображает уникальные ключи назначения М ар Описывает элемент карты (пару “ключ-значение”). Это — вложенный класс интерфейса
Мар
NavigableMap
Расширяет интерфейс
SortedMap для обработки извлечения элементов на основе поиска по ближайшему соответствию
SortedMap
Расширяет
Мар таким образом, что ключи располагаются в порядке по возрастанию
Ниже каждый из этих интерфейсов рассматривается более подробно.
Интерфейс
Мар
Интерфейс
Мар соотносит уникальные ключи со значениями. Ключ —
это объект, который вы используете для последующего извлечения данных. Задавая ключи значение, вы можете помещать значения в объект карты. После того как это значение сохранено, вы можете получить его по ключу. Интерфейс
Мар
— это обобщенный интерфейс, объявленный так, как показано ниже Мар<К, У>

Здесь К указывает тип ключей, а У — тип хранимых значений.
Методы, объявленные в интерфейсе
Мар, собраны в табл. 17.13. Несколько методов передают исключение
ClassCastExcept!on, когда объект оказывается несовместимым с элементами карты. Исключение
NullPointerException передается при попытке использовать пустой объект, когда данная карта этого не допускает. Исключение
UnsupportedOperationExcept ion передается при попытке изменить немодифицируемую карту
Таблица 17.13. Методы, определенные в интерфейсе
мар
1   ...   36   37   38   39   40   41   42   43   ...   90


написать администратору сайта