В каких ситуациях я могу использовать Collections.emptyMap()
? В документации сказано, что я могу использовать этот метод, если хочу, чтобы моя коллекция была неизменной.
Зачем мне неизменяемая пустая коллекция? В чем суть?
java
collections
Винот Кумар CM
источник
источник
[NSArray array]
, он возвращает объект, который хотя и не может использоваться, но существует. Таким образом, вы можете играть с ним, как с обычным объектом, и не получить ошибку.Ответы:
Из Effective Java , элемент № 43 -
"Return empty arrays or collections, not null"
демонстрирует возврат пустой коллекции и, возможно, даже демонстрирует использование этихemptyList()
,emptySet()
иemptyMap()
методов в классе Collections для получения пустой коллекции, которая также имеет дополнительное преимущество неизменности. Из пункта №15"Minimize Mutability"
.Из коллекций-emptySet-Collections-emptyList-Collections
Примечание. Ниже приведен пример кода (измените его в соответствии с вашим вариантом использования):
private Set myset = Collections.emptySet(); void initSet() { myset = new HashSet(); } void deleteSet() { myset = Collections.emptySet(); }
Эти методы предлагают несколько преимуществ:
Они более краткие, потому что вам не нужно явно вводить общий тип коллекции - он обычно просто выводится из контекста вызова метода.
Они более эффективны, потому что не создают новых объектов; они просто повторно используют существующий пустой и неизменный объект. Этот эффект обычно очень незначителен, но иногда (ну, редко) важен.
источник
Set
иHashSet
в ваших примерах, поскольку весь смыслemptySet()
метода и его друзей (в отличие от константCollections.EMPTY_SET
и т. Д.) Заключается в том, что они хорошо работают с дженериками. Кроме того, использование функции (необработанные типы), которая устарела с Java 5, не является хорошим учебным пособием.Collection
вместо того,null
чтобы неExceptions
быть брошенным на следующие операции? Я полагаю, что использование неизменяемой коллекции приведет к какому-то другому исключению. И присвоениеnull
определенно не менее эффективно, чем присвоение неизменной константы.public boolean setExists() { return !myset.equals(Collections.emptySet()); }
По моему личному опыту, это очень полезно в тех случаях, когда API требует набора параметров, а вам нечего предоставить. Например, у вас может быть API, который выглядит примерно так и не допускает пустых ссылок:
public ResultSet executeQuery(String query, Map<String, Object> queryParameters);
Если у вас есть запрос, который не принимает никаких параметров, безусловно, немного расточительно создавать HashMap, который включает выделение массива, когда вы можете просто передать `` Пустую карту '', которая фактически является константой, как это реализовано в
java.util.Collections
.источник
Здесь есть две разные концепции, которые кажутся странными, если рассматривать их вместе. Будет больше смысла, если рассматривать эти две концепции по отдельности.
Во-первых, вы должны по возможности использовать неизменяемую коллекцию, а не изменяемую. Преимущества иммунитета хорошо описаны в других источниках .
Во-вторых, вы должны предпочесть использовать пустую коллекцию, а не использовать null в качестве дозорного. Здесь это хорошо описано . Это означает, что у вас будет гораздо более чистый и понятный код с меньшим количеством мест, где можно спрятать ошибки.
Поэтому, когда у вас есть код, для которого требуется карта, лучше передать пустую карту, а не ноль, чтобы указать на отсутствие карты. И в большинстве случаев, когда вы используете карту, лучше использовать неизменяемую карту. Вот почему есть вспомогательная функция для создания неизменяемой пустой карты.
источник
Есть несколько случаев, когда вы бы предпочли использовать неизменяемые карты, списки, наборы или другие типы коллекций.
Первый и, возможно, наиболее важный вариант использования - всякий раз, когда вы возвращаете результат запроса или вычисления, которые возвращают набор (или список, или карту) результатов, вам следует предпочесть использовать неизменяемые структуры данных.
В этом случае я предпочитаю возвращать неизменяемые их версии, поскольку это гораздо более четко отражает фактическую неизменность набора результатов вычисления - независимо от того, что вы делаете с данными позже, набор результатов, полученных вами из вашего запроса, не должен изменение.
Второй распространенный вариант использования - это когда вам нужно предоставить аргумент в качестве входных данных для метода или службы. Если вы не ожидаете, что входная коллекция будет изменена службой или методом (что обычно является очень плохой дизайнерской идеей), передача неизменяемой коллекции вместо изменяемой во многих случаях может быть разумным и безопасным выбором.
Я думаю об этом как о соглашении о передаче по значению .
В более общем плане - разумно использовать неизменяемые структуры данных всякий раз, когда данные пересекают границы модуля или службы. Это значительно упрощает рассуждение о различиях между (неизменяемым) вводом / выводом и изменяемым внутренним состоянием.
В качестве очень полезного побочного эффекта это повышенная безопасность и безопасность потоков ваших модулей / служб и обеспечение более четкого разделения проблем.
Еще одна веская причина использовать
Collections.empty*()
методы - их заметная неполнота. В эпоху до Java7, если у вас была общая коллекция, вам приходилось разбрасывать аннотации универсального типа повсюду.Просто сравните эти два объявления:
Map<Foo, Comparable<? extends Bar>> fooBarMap = new HashMap<Foo, Comparable<? extends Bar>>();
против:
Последний явно выигрывает в удобочитаемости двумя важными способами:
fooBarMap
присваивается другое непустое значение, просто выполнив поиск/fooBarMap =/
.источник
Во-первых, вы можете обойтись без ссылки. Для и
new HashMap()
т. Д. Потребуется выделенный объект и, возможно, некоторые дополнительные элементы для хранения данных, но вам понадобится только одна копия неизменной пустой коллекции (список, набор, карта или любой другой такой). Это делает очевидным выбор, когда вызываемый вами метод должен принимать карту, но не требует ее редактирования.Я предлагаю проверить эффективную Java Джоша Блоха , в которой перечислены некоторые очень хорошие атрибуты неизменяемых объектов (включая безопасность потоков).
источник
Это может быть полезно, когда у вас есть функция, которая возвращает,
immutable collection
и в некоторых ситуациях нет данных для возврата, поэтому вместо возвратаnull
вы можете вернутьemptyMap()
Это упростит ваш код и предотвратит
NullPointerException
источник
В большинстве случаев мы используем a
constructor
для создания новогоempty map
. НоCollections
methods
предложение несколько преимуществ создать сempty map
помощьюstatic
method
java.util.Collections.emptyMap()
источник
По той же причине, по которой вы когда-
Collections.unmodifiableMap()
нибудь использовали . Вы хотите вернуть экземпляр Map, который выдает исключение, если пользователь пытается его изменить. Это просто особый случай: пустая карта.источник
По тем же причинам, почему вам могут понадобиться неизменяемые объекты. В первую очередь потому, что вы можете спокойно спать по ночам, зная, что несколько потоков могут получить доступ к одному и тому же экземпляру объекта и что все они будут видеть одни и те же значения. Отсутствие элементов в коллекции по-прежнему является допустимым значением, которое вы хотели бы сохранить.
источник