Collection
Определение
java.util.Collection<E> — корневой интерфейс для контейнеров, которые представляют группу элементов. От него наследуются List, Set и Queue. Интерфейс Map стоит отдельно: карта хранит пары «ключ — значение», а не просто элементы.
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object value);
boolean add(E value);
boolean remove(Object value);
Iterator<E> iterator();
// bulk-операции, массивы, Stream API и другие методы
}Программировать через Collection полезно, когда вызывающему коду не нужны порядок, индекс или уникальность:
int countLongNames(Collection<String> names) {
int count = 0;
for (String name : names) {
if (name.length() >= 8) {
count++;
}
}
return count;
}Метод примет и список, и множество. Если контракт требует сохранить порядок или дубликаты, тип Collection уже слишком общий — нужен List.
Основные группы операций
| Группа | Методы | Смысл |
|---|---|---|
| Состояние | size, isEmpty, contains | узнать размер и проверить наличие |
| Изменение | add, remove, clear | изменить содержимое |
| Массовые операции | addAll, removeAll, retainAll, containsAll | работать с другой коллекцией |
| Обход | iterator, forEach, spliterator | последовательно обработать элементы |
| Представление | toArray | получить массив |
| Поток | stream, parallelStream | построить конвейер Stream API |
Часть операций является необязательной. Немодифицируемая коллекция может реализовать add и remove выбрасыванием UnsupportedOperationException. Поэтому тип Collection<E> сам по себе не обещает возможность изменения.
Collection и Collections
Collection— интерфейс экземпляра коллекции.Collections— утилитный класс со статическими алгоритмами и фабриками: сортировка, поиск, перестановка, немодифицируемые представления и другие операции.
List<Integer> numbers = new ArrayList<>(List.of(3, 1, 2));
Collections.sort(numbers);
Collection<Integer> readOnlyView = Collections.unmodifiableCollection(numbers);unmodifiableCollection создаёт представление, а не копию. Изменения исходной коллекции будут видны через него. Для независимого неизменяемого снимка обычно создают копию, например List.copyOf(source).
Инварианты и ловушки
containsиremove(Object)обычно опираются наequals; для хеш-реализаций важен такжеhashCode.- Во время обхода нельзя произвольно менять обычную коллекцию через неё саму: используйте
Iterator.remove, специальную concurrent-реализацию или сначала соберите изменения. size()у большинства коллекций —O(1), но интерфейс не задаёт алгоритмическую сложность.- Допустимость
null, порядок обхода и потокобезопасность определяет конкретная реализация. remove(1)уList<Integer>удаляет элемент по индексу; для удаления значения нуженremove(Integer.valueOf(1)).
Вопросы на собеседовании
- Почему
Mapне наследуетCollection? - Чем
Collectionотличается отCollections? - Что означает «необязательная операция» в контракте коллекции?
- Чем немодифицируемое представление отличается от неизменяемой копии?
- Когда параметр метода стоит объявлять как
Collection, а когда какList?
Связанные заметки
Иерархия коллекций · List · Set · Queue and Deque · Map · Iterable · Equals и hashCode