Collections.emptyList() против нового экземпляра

На практике лучше вернуть пустой список, например this:

return Collections.emptyList();

Или как this:

return new ArrayList<Foo>();

Или это полностью зависит от того, что вы собираетесь делать с возвращенным списком?

Ответ 1

Основное отличие состоит в том, что Collections.emptyList() возвращает неизменный список, т.е. список, к которому вы не можете добавить элементы.

В редких случаях, когда вы хотите изменить возвращенный список, это, таким образом, не будет вариантом.

Я бы сказал, что возвращение неизменяемого списка прекрасно (и даже предпочтительный вариант), пока контракт (документация) явно не говорит иначе.


Кроме того, emptyList() может не создавать новый объект с каждым вызовом.

Реализации этого метода не должны создавать отдельный объект List для каждого вызова. Использование этого метода, вероятно, будет иметь сопоставимые затраты на использование поля с похожими именами. (В отличие от этого метода, поле не обеспечивает безопасность типа.)

Реализация emptyList выглядит следующим образом:

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

Итак, если ваш метод (который возвращает пустой список) вызывается очень часто, этот подход может даже дать вам немного лучшую производительность как процессора, так и памяти.

Ответ 2

Начиная с Java 5.0 вы можете указать тип элемента в контейнере:

Collections.<Foo>emptyList()

Я согласен с другими ответами, что для случаев, когда вы хотите вернуть пустой список, который остается пустым, вы должны использовать этот подход.

Ответ 3

Collections.emptyList является неизменным, поэтому существует разница между двумя версиями, поэтому вы должны учитывать пользователей возвращаемого значения.

Возврат new ArrayList<Foo> всегда создает новый экземпляр объекта, поэтому он имеет очень небольшую дополнительную стоимость, связанную с ним, что может дать вам основание использовать Collections.emptyList. Мне нравится использовать emptyList только потому, что это более читаемо.

Ответ 4

Будьте осторожны, хотя. Если вы возвращаете Collections.emptyList() и затем пытаетесь внести в него некоторые изменения, такие как add() или что-то в этом роде, у вас будет UnsupportedOperationException() потому что Collections.emptyList() возвращает неизменный объект.

Ответ 5

Я бы пошел с Collections.emptyList(), если возвращаемый список никоим образом не изменяется (поскольку список является неизменным), в противном случае я бы пошел с опцией 2.

Преимущество Collections.emptyList() заключается в том, что один и тот же статический экземпляр возвращается каждый раз, и поэтому для каждого вызова не возникает создание экземпляра.

Ответ 6

Используйте Collections.emptyList(), если вы хотите, чтобы возвращаемый список никогда не был изменен. Это то, что возвращается при вызове метода emptyList():

/**
 * The empty list (immutable). 
 */
public static final List EMPTY_LIST = new EmptyList();

Ответ 7

В приведенных ответах подчеркивается тот факт, что emptyList() возвращает неизменяемый List, но не дает альтернатив. Конструктивные ArrayList(int initialCapacity) специальные случаи 0, поэтому возвращение new ArrayList<>(0) вместо new ArrayList<>() также может быть жизнеспособным решением:

/**
 * Shared empty array instance used for empty instances.
 */
private static final Object[] EMPTY_ELEMENTDATA = {};

[...]

/**
 * Constructs an empty list with the specified initial capacity.
 *
 * @param  initialCapacity  the initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

(источники из Java 1.8.0_72)