Коллекции.emptyMap () vs new HashMap()
Каковы некоторые из ситуаций, когда я могу использовать Collections.emptyMap() ? В документации говорится, что я могу использовать этот метод, если хочу, чтобы моя коллекция была неизменной.
зачем мне нужна неизменяемая пустая коллекция? Какой в этом смысл?
9 ответов:
С Эффективная Java,пункт #43 -
"Return empty arrays or collections, not null"демонстрирует возврат пустой коллекции и, возможно, даже демонстрирует использование этихemptyList(),emptySet()иemptyMap()методы в классе Collections для получения пустой коллекции, которая также имеет дополнительное преимущество быть неизменяемой. От пункт #15"Minimize Mutability".С коллекции-emptySet-коллекции-emptyList-коллекции
его типа языков программирования. Это для людей, которые не хотят нулевые переменные. Поэтому, прежде чем набор будет инициализирован, они могут использовать пустой набор.
Примечание: ниже код просто пример (изменить его в соответствии с вашим прецедентом):
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);Если у вас есть запрос, который не принимает никаких параметров, конечно, немного расточительно создавать хэш-карту, которая включает в себя выделение массива, когда вы можете просто передать "пустую карту", которая фактически является константа, как это реализовано в
java.util.Collections.
зачем мне нужна неизменяемая пустая коллекция? Какой в этом смысл?
здесь есть две разные концепции, которые кажутся странными при просмотре вместе. Это имеет больше смысла, когда вы рассматриваете эти два понятия отдельно.
во-первых, вы должны предпочесть использовать неизменяемую коллекцию, а не изменяемую, где это возможно. Преимущества неизменности хорошо документально в другом месте.
во-вторых, вы должны предпочесть использовать пустую коллекцию, а не использовать null в качестве стража. Это хорошо описано здесь. Это означает, что у вас будет гораздо чище, легче понять код, с меньшим количеством мест для ошибок, чтобы скрыть.
поэтому, когда у вас есть код, который требует карту, лучше сдать пустую карту, а не null, чтобы указать на отсутствие карты. И большую часть времени, когда вы используя карту, лучше использовать неизменяемую карту. Так вот почему есть функция удобства, чтобы сделать неизменяемую пустую карту.
есть несколько случаев, когда вы предпочитаете использовать неизменяемые карты, списки, наборы или другие типы коллекций.
первый и, возможно, наиболее важным вариантом использования является всякий раз, когда вы возвращаете результат запроса или вычисления, которые возвращают набор (или список или карту) результатов, вы должны предпочесть использовать неизменяемые структуры данных.
в этом случае я предпочитаю возвращать неизменяемые версии этих, поскольку это отражает фактическую неизменность a результирующий набор вычислений гораздо более четко - независимо от того, что вы делаете с данными позже, набор результатов, полученных от вашего запроса, не должен меняться.
второй распространены случаи, когда нужно предоставить аргумент в качестве входных данных для метода или сервиса. Если только ты ожидал входная коллекция должна быть изменена службой или методом (что обычно является очень плохой идеей дизайна), передавая неизменяемую коллекцию вместо изменяемой быть разумным и безопасным выбором во многих случаях.
Я думаю об этом как "передать по значению" конвенции.
в целом - разумно использовать неизменяемые структуры данных всякий раз, когда данные пересекают границы модуля или службы. Это значительно облегчает рассуждение о различиях между (неизменяемым) входом/выходом и изменяемым внутренним состоянием.
как очень полезный побочный эффект это повышение безопасности и потокобезопасность ваших модулей / услуг и обеспечивает более чистое разделение проблем.
еще одна веская причина использовать
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 =/.
во-первых, вы можете уйти с поделиться ссылкой. А
new HashMap()etc потребует выделенного объекта и, возможно, некоторых дополнительных элементов для хранения данных, но вам нужна только одна копия неизменяемой пустой коллекции (список, набор, карта или любой другой такой). Это делает его очевидным выбором, когда метод, который вы вызываете, должен принимать карту, но не должен ее редактировать.Я предлагаю проверить Эффективная Java, в котором перечислены некоторые очень хорошие атрибуты неизменяемые объекты (включая потокобезопасность).
это может быть полезно, когда у вас есть функция, которая возвращает
immutable collectionи в некоторых ситуациях нет данных, чтобы вернуть так вместо возвращенияnullвы можете вернутьemptyMap()это сделать ваш код проще и предотвратить
NullPointerException
зачем мне нужна неизменяемая пустая коллекция? Какой в этом смысл?
по той же причине вы могли бы использовать
Collections.unmodifiableMap()в какой-то момент. Вы хотите вернуть экземпляр карты, который создает исключение, если пользователь пытается его изменить. Это просто особый случай: пустая карта.
большую часть времени мы используем
constructorсоздать новыйempty map. Но этоCollectionsmethodsпредложит несколько преимуществ для созданияempty mapС помощьюstaticmethodjava.util.Collections.emptyMap()
они более лаконичны, потому что вам не нужно явно вводить общий тип коллекции - это обычно просто выводится из контекст вызова метода.
они более эффективны, потому что они не беспокоятся о создании новых объекты; они просто повторно используют существующий пустой и неизменяемый объект. Этот эффект, как правило, очень незначительный, но это иногда (ну, редко) важный.
зачем мне нужна неизменяемая пустая коллекция? Какой в этом смысл?
по тем же причинам, по которым вам могут понадобиться неизменяемые объекты. В первую очередь потому, что вы можете спать спокойно ночью, зная, что несколько потоков могут получить доступ к одному и тому же экземпляру объекта и что все они будут видеть одни и те же значения. Отсутствие элементов в коллекции по-прежнему является допустимым значением, которое вы хотите сохранить.
Comments