Collections.emptyList () против нового экземпляра - PullRequest
216 голосов
/ 05 апреля 2011

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

return Collections.emptyList();

Или как this :

return new ArrayList<Foo>();

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

Ответы [ 7 ]

270 голосов
/ 05 апреля 2011

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

В тех редких случаях, когда вы делаете хотите изменить возвращаемый список, Collections.emptyList() и List.of(), таким образом, не - хороший выбор.

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


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

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

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

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

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

47 голосов
/ 13 октября 2011

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

Collections.<Foo>emptyList()

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

26 голосов
/ 05 апреля 2011

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

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

11 голосов
/ 06 июля 2016

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

6 голосов
/ 05 апреля 2011

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

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

2 голосов
/ 24 апреля 2012

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

/**
 * The empty list (immutable). 
 */
public static final List EMPTY_LIST = new EmptyList();
1 голос
/ 15 февраля 2016

В данных ответах подчеркивается тот факт, что 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)

...