Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

В строках 7 и 8 из List успешно удаляется заданный объект. Строка 9 и предшествующий ей код демонстрируют вставку элемента в середину списка. Метод subList позволяет легко создать «срез» из подмножества элементов списка; естественно, при передаче его методу containsAll большего списка будет получен истинный результат. Вызовы Collections.sort и Collec-tions.shuffle для sub не влияют на результат вызова containsAll.

Метод retainAll фактически выполняет операцию «пересечения множеств», то есть определения всех элементов сору, которые также присутствуют в sub. И снова поведение

метода зависит от реализации equals.

В строке 14 представлен результат удаления элемента по индексу — это проще, чем удаление по ссылке на объект, потому что вам не придется беспокоиться о поведении equals.

Работа метода 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). Итератор — это объект, обеспечивающий перемещение по последовательности объектов с выбором каждого объекта этой последовательности, при этом программисту-клиенту не надо знать или заботиться о лежащей в ее основе структуре. Вдобавок, итератор обычно является так называемым «легковесным» (lightweight) объектом: его создание должно обходиться без заметных затрат ресурсов. Из-за этого итераторы часто имеют ограничения; например, 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 отсутствует информация о типе последовательности, и в этом проявляется истинная мощь итераторов: операция перемещения по последовательности отделяется от фактической структуры этой последовательности. Иногда говорят, что итераторы унифицируют доступ к контейнерам.

Поделиться:
Популярные книги

Хорошая девочка

Кистяева Марина
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Хорошая девочка

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

Черный Маг Императора 10

Герда Александр
10. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 10

Одержимый

Поселягин Владимир Геннадьевич
4. Красноармеец
Фантастика:
боевая фантастика
5.00
рейтинг книги
Одержимый

Фиктивная жена

Шагаева Наталья
1. Братья Вертинские
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Фиктивная жена

Хозяин Теней 3

Петров Максим Николаевич
3. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Хозяин Теней 3

Маленькая хозяйка большого герцогства

Вера Виктория
2. Герцогиня
Любовные романы:
любовно-фантастические романы
7.80
рейтинг книги
Маленькая хозяйка большого герцогства

Курсант: Назад в СССР 10

Дамиров Рафаэль
10. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: Назад в СССР 10

Гридень 2. Поиск пути

Гуров Валерий Александрович
2. Гридень
Детективы:
исторические детективы
5.00
рейтинг книги
Гридень 2. Поиск пути

Ищу жену для своего мужа

Кат Зозо
Любовные романы:
любовно-фантастические романы
6.17
рейтинг книги
Ищу жену для своего мужа

Оружие победы

Грабин Василий Гаврилович
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Оружие победы

Звездная Кровь. Изгой II

Елисеев Алексей Станиславович
2. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
технофэнтези
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой II

Конунг Туманного острова

Чайка Дмитрий
12. Третий Рим
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Конунг Туманного острова

Свет во мраке

Михайлов Дем Алексеевич
8. Изгой
Фантастика:
фэнтези
7.30
рейтинг книги
Свет во мраке