88

88


Работа метода removeAll() также зависит от equals(). Как подсказывает назва­ние, метод удаляет из List все объекты, входящие в List-аргумент.

Название метода set() выбрано неудачно, потому что оно совпадает с именем класса Set — возможно, лучше было бы назвать метод «replace», потому что он заменяет элемент с заданным индексом (первый аргумент) вторым аргументом.

В строке вывода 17 показано, что для List существует перегруженный метод addAll(), вставляющий новый список в середину исходного списка (вместо про­стого добавления в конец методом addAll(), унаследованным от Collection).

В строках 18-20 представлен результат вызова методов isEmpty() и clear(). Строки 22 и 23 демонстрируют, что любой объект Collection можно преобразо­вать в массив с использованием to Array ().

Итераторы

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

Если взглянуть на ситуацию с более высокого уровня, обнаруживается про­блема: чтобы использовать контейнер в программе, необходимо знать его точ­ный тип. Что, если вы начали использовать в программе контейнер List, а затем обнаружили, что в вашем случае будет удобнее применить тот же код к множе­ству (Set)? Или если вы хотите написать универсальный код, который не зави­сит от типа контейнера и может применяться к любому контейнеру?

С данной абстракцией хорошо согласуется концепцияитератора(iterator). Итератор — это объект, обеспечивающий перемещение по последовательности объектов с выбором каждого объекта этой последовательности, при этом про­граммисту-клиенту не надо знать или заботиться о лежащей в ее основе струк­туре. Вдобавок, итератор обычно является так называемым «легковесным» (light­weight) объектом: его создание должно обходиться без заметных затрат ресур­сов. Из-за этого итераторы часто имеют ограничения; например, Iterator в Java поддерживает перемещение только в одном направлении. Его возможности не так уж широки, но с его помощью можно сделать следующее:

•        Запросить у контейнера итератор вызовом метода iterator(). Получен­ный итератор готов вернуть начальный элемент последовательности при первом вызове своего метода next().

•        Получить следующий элемент последовательности вызовом метода next().

•        Проверить, остались ли еще объекты в последовательности (метод hasNext()).

•        Удалить из последовательности последний элемент, возвращенный ите­ратором, методом remove().

Чтобы увидеть итератор в действии, мы снова воспользуемся иерархией Pets:

// holding/Simplelteration java import typeinfo pets *; import java util *.

public class Simplelteration {

public static void main(String[] args) {

List<Pet> pets = Pets arrayList(12); Iterator<Pet> it = pets iteratorO. whi 1 e(it hasNextO) {

Pet p = it nextO;

System.out pri nt(p id() + " " + p + " ");

}

System.out printlnO; // Более простой способ, for(Pet p • pets)

System out print(p id() + "+ p + " "); System, out. printlnO;

// Итератор также способен удалять элементы: it = pets. iteratorO. for(int i = 0: i < 6: i++) { it nextO: it.removeO.

}

System.out.pnntln(pets):

}

} /* Output-

0:Rat l:Manx 2:Cymric 3-Mutt 4-Pug 5:Cymric 6.Pug 7:Manx 8.Cymric 9:Rat 10:EgyptianMau 11.Hamster

0-Rat 1-Manx 2-Cymric 3:Mutt 4:Pug 5.Cymric 6:Pug 7:Manx 8:Cymric 9-Rat 10-EgyptianMau 11:Hamster

[Pug. Manx. Cymric. Rat. EgyptianMau. Hamster] *///•-

Мы видим, что с Iterator можно не беспокоиться о количестве элементов в последовательности. Проверка осуществляется методами hasNext() и next().

Если вы просто перебираете элементы списка в одном направлении, не пы­таясь модифицировать его содержимое, «синтаксис foreach» обеспечивает более компактную запись.

Iterator удаляет последний элемент, полученный при помощи next(), поэтому перед вызовом remove() необходимо вызвать next().

Теперь рассмотрим задачу создания метода display(), не зависящего от типа контейнера:

//: hoiding/CrossContaiпегIteration.java import typeinfo.pets.*, import java.util *;

public class CrossContainerlteration {

public static void display(Iterator<Pet> it) { while(it.hasNextO) {

Pet p = it nextO:

System.out.print(p.id() + ":" + p + " ");

}

System out.printlnO;

}

public static void main(String[] args) {продолжение &

ArrayList<Pet> pets = Pets.arrayList(8); LinkedList<Pet> petsLL = new LinkedList<Pet>(pets); HashSet<Pet> petsHS = new HashSet<Pet>(pets); TreeSet<Pet> petsTS = new TreeSet<Pet>(pets); di splay(pets.iterator()); display(petsLL iteratorO); di splay(petsHS.iterator()); di spl ay(petsTS. iteratorO);

}

} /* Output:

0:Rat 1-Manx 2-Cymric 3-Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 0:Rat l.Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 4:Pug 6:Pug 3:Mutt l:Manx 5:Cymric 7:Manx 2:Cymric 0:Rat 5 Cymric 2:Cymric 7:Manx l:Manx 3:Mutt 6:Pug 4:Pug 0:Rat *///:-

В методе display() отсутствует информация о типе последовательности, и в этом проявляется истинная мощь итераторов: операция перемещения по по­следовательности отделяется от фактической структуры этой последовательно­сти. Иногда говорят, что итераторыунифицируют доступ к контейнерам.

Listlterator

Listlterator — более мощная разновидность Iterator, поддерживаемая только классами List. Если Iterator поддерживает перемещение только вперед, List- Iterator является двусторонним. Кроме того, он может выдавать индексы сле­дующего и предыдущего элементов по отношению к текущей позиции итерато­ра в списке и заменять последний посещенный элемент методом set(). Вызов listIterator() возвращает Listlterator, указывающий в начало List, а для создания итератора Listlterator, изначально установленного на элемент с индексом п, ис­пользуется вызов listlterator(n). Все перечисленные возможности продемонст­рированы в следующем примере:

//: hoiding/Listlteration java import typeinfo.pets.*, import java.util *;

public class Listlteration {

public static void main(String[] args) {

List<Pet> pets = Pets.arrayList(8); ListIterator<Pet> it = pets.listlteratorO; while(it.hasNextO)

Report Page