Иерархия Collections Framework
Java Collections Framework — это набор интерфейсов и классов для работы с группами объектов. Основные интерфейсы:
ArrayList
▸Внутренняя реализация
ArrayList — это обёртка над массивом Object[]. При добавлении элементов, если массив заполнен, создаётся новый массив в 1.5 раза больше, и элементы копируются.
1public class ArrayList<E> extends AbstractList<E> {2 private static final int DEFAULT_CAPACITY = 10;3 private Object[] elementData;4 private int size;56 public boolean add(E e) {7 ensureCapacityInternal(size + 1);8 elementData[size++] = e;9 return true;10 }1112 private void ensureCapacityInternal(int minCapacity) {13 if (minCapacity > elementData.length)14 grow(minCapacity);15 }1617 private void grow(int minCapacity) {18 int oldCapacity = elementData.length;19 int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5x20 elementData = Arrays.copyOf(elementData, newCapacity);21 }22}
▸Сложность операций
LinkedList
▸Внутренняя реализация
LinkedList — это двусвязный список. Каждый элемент (Node) содержит ссылки на предыдущий и следующий элементы.
1public class LinkedList<E> extends AbstractSequentialList<E> {2 transient int size = 0;3 transient Node<E> first;4 transient Node<E> last;56 private static class Node<E> {7 E item;8 Node<E> next;9 Node<E> prev;1011 Node(Node<E> prev, E element, Node<E> next) {12 this.item = element;13 this.next = next;14 this.prev = prev;15 }16 }17}
▸Сложность операций
HashMap
▸Внутренняя реализация
HashMap использует массив Node[] (называемый table) с связным списком для разрешения коллизий. Начиная с Java 8, при размере цепочки > 8 элементов она заменяется на красно-чёрное дерево (TreeBin).
1public class HashMap<K,V> {2 static final int DEFAULT_INITIAL_CAPACITY = 16;3 static final float DEFAULT_LOAD_FACTOR = 0.75f;45 transient Node<K,V>[] table;6 transient int size;7 int threshold;8 final float loadFactor;910 public V put(K key, V value) {11 return putVal(hash(key), key, value, false, true);12 }1314 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {15 Node<K,V>[] tab; Node<K,V> p; int n, i;16 if ((tab = table) == null || (n = tab.length) == 0)17 n = (tab = resize()).length;18 if ((p = tab[i = (n - 1) & hash]) == null)19 tab[i] = newNode(hash, key, value, null);20 else {21 // Обработка коллизий...22 }23 }24}
▸Key-моменты
hash = key.hashCode() ^ (h >>> 16)(n-1) & hash▸Сложность операций
Другие важные коллекции
▸HashSet
Внутренняя обёртка над HashMap. Элементы хранятся как ключи, значения — фиктивный Object.
▸TreeMap
Красно-чёрное дерево. O(log n) для всех операций. Элементы отсортированы.
▸ConcurrentHashMap
Потокобезопасный HashMap. Использует сегментирование (Java 7) или CAS + synchronized (Java 8).
▸Queue/Deque
Когда что использовать
▸ArrayList vs LinkedList
▸HashMap vs TreeMap vs LinkedHashMap
Практические советы
▸Инициализация с начальной ёмкостью
1// Если знаем размер — лучше сразу указать2Map<String, User> users = new HashMap<>(expectedSize * 4 / 3 + 1);
▸Immutable Collections
1List<String> immutable = List.of("a", "b", "c");2Map<String, Integer> map = Map.of("one", 1, "two", 2);
Заключение
Понимание внутренней реализации Java Collections — обязательная тема для собеседования. Знайте разницу в сложности операций, когда использовать ArrayList vs LinkedList, как работает хэширование в HashMap. Эти знания помогают принимать обоснованные решения о производительности.