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