Ответ
Set и ArrayList — это реализации разных интерфейсов коллекций в Java с фундаментально различными свойствами и целями использования.
Сравнительная таблица:
| Характеристика | ArrayList<E> (Реализация List<E>) |
Set<E> (Интерфейс, например, HashSet<E>, TreeSet<E>) |
|---|---|---|
| Основной контракт | Упорядоченная последовательность. Гарантирует порядок вставки элементов. | Неупорядоченное множество уникальных элементов. Гарантирует отсутствие дубликатов. |
| Дубликаты | Разрешены. Можно добавить несколько equals()-объектов. |
Запрещены. Добавление элемента, который уже есть в множестве (по equals()), игнорируется. |
| Доступ к элементам | По индексу (позиции) через get(int index). Эффективен (O(1)). |
Нет доступа по индексу. Можно только проверить наличие (contains()), перебрать итератором или преобразовать в массив. |
| Нулевые значения | Разрешены. | Зависит от реализации. HashSet разрешает один null, TreeSet — нет (выбрасывает NullPointerException). |
| Основные реализации | ArrayList, LinkedList, Vector. |
HashSet (быстрый доступ, нет порядка), LinkedHashSet (порядок вставки), TreeSet (сортированный порядок). |
Производительность contains() |
O(n) в худшем случае (линейный поиск). |
O(1) в среднем для HashSet (поиск по хэшу). |
Примеры кода:
import java.util.*;
public class CollectionDifference {
public static void main(String[] args) {
// --- ArrayList (List) ---
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Apple"); // Дубликат РАЗРЕШЕН
list.add(null); // null РАЗРЕШЕН
System.out.println("ArrayList: " + list); // [Apple, Banana, Apple, null]
System.out.println("Элемент с индексом 1: " + list.get(1)); // "Banana"
// --- HashSet (Set) ---
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Apple"); // Дубликат ИГНОРИРУЕТСЯ
set.add(null); // null РАЗРЕШЕН (для HashSet)
System.out.println("HashSet: " + set); // Порядок не гарантирован: [null, Apple, Banana]
// set.get(1); // ОШИБКА! Метода get(int) не существует.
System.out.println("Содержит 'Banana'? " + set.contains("Banana")); // true
// --- LinkedHashSet (сохраняет порядок вставки) ---
Set<String> linkedSet = new LinkedHashSet<>();
linkedSet.add("Zebra");
linkedSet.add("Apple");
linkedSet.add("Banana");
System.out.println("LinkedHashSet: " + linkedSet); // [Zebra, Apple, Banana]
}
}
Когда что использовать:
- Используйте
ArrayList(или другойList), когда:- Важен порядок элементов.
- Часто требуется доступ к элементам по их позиции (индексу).
- Допустимы или даже необходимы дублирующиеся значения.
- Используйте
Set(чащеHashSet), когда:- Требуется гарантировать уникальность элементов.
- Нужна быстрая проверка наличия элемента в коллекции (
contains()). - Порядок элементов не важен (или нужен особый:
LinkedHashSetдля порядка вставки,TreeSetдля сортировки).