Метод 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(). Полученный итератор готов вернуть начальный элемент последовательности при первом вызове своего метода 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 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 p = it nextO:
System.out.print(p.id() + ":" + p + " ");
}
System out.printlnO;
}
public static void main(String[] args) {