List.of() появился в Java 9 и произвёл революцию в создании коллекций. Но под капотом это не просто обёртка над ArrayList — это целая иерархия оптимизированных классов.
📦 Сигнатура и варианты
Java предоставляет 12 перегруженных методов:
// Специализированные версии для 0-10 элементов
static <E> List<E> of()
static <E> List<E> of(E e1)
static <E> List<E> of(E e1, E e2)
// ... до 10 параметров
static <E> List<E> of(E e1, E e2, ..., E e10)
// Varargs для 11+ элементов
static <E> List<E> of(E... elements)
Зачем столько перегрузок?
— Избежать overhead создания varargs массива
— Каждая перегрузка возвращает оптимизированный класс
— Специализация для частых случаев (1-2 элемента)
→ Разные классы для разного размера:
// 0 элементов — singleton
static <E> List<E> of() {
return ImmutableCollections.EMPTY_LIST; // Переиспользуется!
}
// 1 элемент — List12 (List of 1 or 2)
static <E> List<E> of(E e1) {
return new ImmutableCollections.List12<>(e1);
}
// 2 элемента — тот же List12
static <E> List<E> of(E e1, E e2) {
return new ImmutableCollections.List12<>(e1, e2);
}
// 3+ элементов — ListN
static <E> List<E> of(E e1, E e2, E e3) {
return ImmutableCollections.listFromTrustedArray(e1, e2, e3);
}
→ Структура List12 (для 1-2 элементов):
static final class List12<E> extends AbstractImmutableList<E> {
private final E e0; // Всегда присутствует
private final E e1; // null если один элемент
List12(E e0) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = null;
}
List12(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
public int size() {
return e1 != null ? 2 : 1;
}
public E get(int index) {
if (index == 0) return e0;
else if (index == 1 && e1 != null) return e1;
throw new IndexOutOfBoundsException();
}
}→ Структура ListN (для 3+ элементов):
static final class ListN<E> extends AbstractImmutableList<E> {
private final E[] elements; // Хранит все элементы
ListN(E... elements) {
// Копирование + null-check каждого элемента
this.elements = elements.clone();
for (E e : this.elements) {
Objects.requireNonNull(e);
}
}
public int size() {
return elements.length;
}
public E get(int index) {
return elements[index];
}
}1. Null элементы запрещены.
2. Varargs создаёт массив.
3. Не Serializable.
4. SubList тоже immutable.
📊 Performance бенчмарк
→ Создание списка из 3 элементов:
List.of("A", "B", "C"): ~5 ns
Arrays.asList("A", "B", "C"): ~8 ns
new ArrayList<>(Arrays.asList(...)): ~25 ns
List.of() в 5 раз быстрее ArrayList!→ Memory footprint:
List.of(1, 2, 3): 48 байт
Arrays.asList(1, 2, 3): ~72 байт (backing array + wrapper)
new ArrayList<>(3 items): ~112 байт (default capacity 10)
List.of() в 2.3 раза компактнее!
🔗 Документация
══════ Навигация ══════
Вакансии • Задачи • Собесы
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤2🔥1