Collections.emptyList: примеры (JAVA)

Примеры и особенности Collections.emptyList
Раздел: Коллекции (Collection Framework) - List
Collections.emptyList: List

Общее описание Collections.emptyList

Метод Collections.emptyList() - статический хелпер из пакета java.util, возвращающий пустой неизменяемый список. Аргументов не принимает. Сигнатура: public static final <T> List<T> emptyList(). Возвращаемый объект представляет собой одиночный (singleton) пустой список с параметром типа, выводимым компилятором или указываемым через присваивание.

Поведение и гарантии

  • Размер списка равен 0, isEmpty() возвращает true.
  • Список неизменяем: вызов методов модификации (add, remove, addAll и т. п.) приводит к UnsupportedOperationException.
  • Экземпляр реализует корректное сравнение по содержимому: равен любому другому пустому списку.
  • Метод безопасен по отношению к типам благодаря обобщениям: его можно присваивать переменной любого параметризованного типа List<T> без создания нового объекта.
  • Реализация обычно представляет собой один и тот же singleton-объект для всех вызовов, что экономит память и позволяет быстрым сравнениям ссылок, но на это полагаться не требуется.

Аргументы

Аргументов нет.

Возвращаемое значение

Возвращается объект типа List<T>, содержащий 0 элементов, поддерживающий операции чтения и бросающий UnsupportedOperationException при попытках модификации. Тип T определяется контекстом присваивания или вызова.

Когда используется

Используется как безопасный пустой результат вместо null, при возврате списка из метода, для оптимизации памяти, при объединении с потоками или при задании значения по умолчанию в параметрах и полях.

Короткие примеры использования

Присвоение и проверка пустоты.

List<String> list = Collections.emptyList();
System.out.println(list.size());
System.out.println(list.isEmpty());
0
true

Попытка модификации вызывает исключение.

List<Integer> nums = Collections.emptyList();
try {
    nums.add(1);
} catch (Exception e) {
    System.out.println(e.getClass().getSimpleName());
}
UnsupportedOperationException

Использование с обобщениями и методами, ожидающими List<T>.

void process(List<String> items) {
    System.out.println(items.size());
}
process(Collections.emptyList());
0

Композиция с потоками: безопасное объединение.

Stream<String> s = Stream.concat(Stream.of("a"), Collections.emptyList().stream());
s.forEach(System.out::println);
a

Аналоги в Java и их особенности

  • List.of()
  • Фабричные методы в Java 9+ (List.of(), Set.of(), Map.of()) возвращают неизменяемые коллекции. List.of() без аргументов эквивалентен пустому списку. Отличие: фабричные методы запрещают null для элементов (если бы они были) и могут возвращать другие реализации; предпочтительнее при использовании Java 9+.

  • Collections.EMPTY_LIST
  • Старый константный объект. Это raw-тип, при присваивании параметризованной переменной будет предупреждение unchecked. Использование emptyList() предпочтительнее из-за строгой типизации.

  • new ArrayList<>()
  • Создает изменяемый пустой список. Предпочтительнее, когда требуется последующая модификация. Стоимость создания объекта выше, чем у singleton из emptyList().

  • Collections.unmodifiableList(someList)
  • Возвращает представление, запрещающее модификации, но если исходный список изменяется, результат меняется. В отличие от emptyList(), этот wrapper связывается с конкретным экземпляром.

Пустые коллекции в других языках

  • Kotlin
  • Функция emptyList<T>() возвращает неизменяемый пустой список и ближе всего по семантике к Java. Пример:

    val lst: List<String> = emptyList()
    (пустой список)
  • C#
  • В .NET есть Enumerable.Empty<T>() и Array.Empty<T>(). Оба возвращают пустую последовательность/массив. Array.Empty удобен для производительности, возвращает тот же экземпляр.

    var e = Enumerable.Empty<int>();
    Console.WriteLine(e.Any());
    False
  • Python
  • Пустой список [] изменяем, пустой кортеж () - неизменяем. Эквивалент неизменяемого пустого списка - пустой кортеж или использование tuple().

    lst = []
    print(len(lst))
    # неизменяемый вариант: tpl = ()
    0
  • JavaScript
  • Пустой массив [] изменяем. Для «неизменяемого» можно использовать Object.freeze([]), но поведение отличается и не такое распространенное.

    const a = [];
    console.log(a.length);
    const b = Object.freeze([]);
    try { b.push(1) } catch(e) { console.log('err') }
    0
    err
  • PHP
  • Пустой массив [] изменяем. Особенность PHP - массивы ассоциативные и копируются по затиранию при изменениях.

    $a = [];
    var_dump(count($a));
    int(0)
  • Go
  • Пустой срез можно представлять как nil или make([]T,0). nil срез и срез нулевой длины отличаются по виду, но часто взаимозаменяемы при чтении.

    var s []int
    fmt.Println(len(s))
    s2 := make([]int,0)
    fmt.Println(len(s2))
    0
    0
  • Lua
  • Пустая таблица {} используется и для массивов, и для словарей; она изменяема.

    t = {}
    print(#t)
    0
  • SQL
  • В реляционном языке понятие «пустой список» чаще выражается пустым набором результатов запроса. Пример: SELECT * FROM table WHERE 1=0 даст нулевые строки.

    -- запрос
    SELECT * FROM users WHERE 1=0;
    (0 строк)

Типичные ошибки при использовании

  • Ожидание изменяемости
  • Частая проблема - попытка добавить элемент в список из Collections.emptyList(), что приводит к UnsupportedOperationException. Пример:

    List<String> l = Collections.emptyList();
    l.add("x");
    Exception in thread "main" java.lang.UnsupportedOperationException
        at java.base/java.util.Collections$EmptyList.add(Collections.java:...)
  • Использование Collections.EMPTY_LIST вместо emptyList()
  • Присваивание Collections.EMPTY_LIST параметризованной переменной вызывает предупреждение unchecked и может скрыть ошибки типов. Пример предупреждения:

    List<String> s = Collections.EMPTY_LIST; // unchecked assignment
    (компилятор выдаст предупреждение unchecked assignment)
  • Неправильная передача в API, ожидающее изменяемый список
  • Если библиотечный метод внутри выполняет модификации переданного списка, передача пустого неизменяемого списка вызовет исключение во время выполнения.

Изменения и примечания по версиям

Сам метод Collections.emptyList() существует давно и существенно не менялся. В Java 9 были добавлены фабрики List.of(), Set.of() и Map.of(), которые в ряде случаев заменяют использование emptyList() и дают более современную семантику неизменяемых коллекций. Основная разница: фабрики Java 9 запрещают null при создании коллекций с элементами и могут возвращать другие реализационные оптимизации.

Расширенные и редкие сценарии применения

Возврат значения по умолчанию вместо null

Пример java
public List<String> findTags(Long id) {
    List<String> tags = dao.getTags(id);
    return tags == null ? Collections.emptyList() : tags;
}
// Вызов:
List<String> t = findTags(1L);
System.out.println(t.size());
0

Использование в сигнатурах generic методов для удобства типов

Пример java
public <T> List<T> emptyIfNull(List<T> src) {
    return src == null ? Collections.emptyList() : src;
}
List<Integer> r = emptyIfNull(null);
System.out.println(r.getClass());
class java.util.Collections$EmptyList

Композиция с потоками и коллекторами как поставщик по умолчанию

Пример java
List<String> result = Optional.ofNullable(fetch())
    .orElse(Collections.emptyList())
    .stream()
    .filter(s -> s.startsWith("a"))
    .collect(Collectors.toList());
System.out.println(result);
[]

Передача в методы, где ожидается неизменяемое представление

Пример java
someApi.process(Collections.emptyList());
// Если process не пытаетcя модифицировать коллекцию - это оптимально по памяти
(зависит от реализации someApi)

Сравнение производительности и памяти

Для частых возвратов пустого результата Collections.emptyList() эффективнее создания нового ArrayList<>() за счет повторного использования объекта. При необходимости модификации предпочтителен новый пустой список.

джава Collections.emptyList function comments

En
Collections.emptyList Returns an empty list (immutable)