UnmodifiableMap (коллекции Java) против ImmutableMap (Google)
Контекст
Мне нужно вернуть ссылку на карту, которую я использую для кеша данных, и я хотел бы удостовериться, что никто не может изменить их ссылку.
Вопрос
Я видел много ссылок на UnmodifiableMap и ImmutableMap в Интернете, но я не вижу ничего, сравнивая/противопоставляя их. Я полагаю, что есть веская причина, по которой Google/Guava создали свою собственную версию - может кто-нибудь сказать мне, что это такое?
Ответы
Ответ 1
Модифицируемая карта может по-прежнему меняться. Это только взгляд на модифицируемую карту, и изменения в карте поддержки будут видны через немодифицируемую карту. Немодифицируемая карта только предотвращает модификации для тех, у кого есть только ссылка на немодифицируемое представление:
Map<String, String> realMap = new HashMap<String, String>();
realMap.put("A", "B");
Map<String, String> unmodifiableMap = Collections.unmodifiableMap(realMap);
// This is not possible: It would throw an
// UnsupportedOperationException
//unmodifiableMap.put("C", "D");
// This is still possible:
realMap.put("E", "F");
// The change in the "realMap" is now also visible
// in the "unmodifiableMap". So the unmodifiableMap
// has changed after it has been created.
unmodifiableMap.get("E"); // Will return "F".
В отличие от этого, ImmutableMap из Guava действительно неизменен: это настоящая копия данной карты, и никто не может каким-либо образом модифицировать эту ImmutableMap.
Обновить:
Как указано в comment, неизменяемая карта также может быть создана со стандартным API, используя
Map<String, String> immutableMap =
Collections.unmodifiableMap(new LinkedHashMap<String, String>(realMap));
Это создаст немодифицируемый вид на истинную копию данной карты и, таким образом, красиво эмулирует характеристики ImmutableMap
, не добавляя зависимостей к Guava.
Ответ 2
Посмотрите на ImmutableMap JavaDoc: doc
Там есть информация об этом:
В отличие от Collections.unmodifiableMap(java.util.Map), который представляет собой вид отдельной карты, которая все еще может изменяться, экземпляр ImmutableMap содержит свои собственные данные и никогда не изменится. ImmutableMap удобен для общедоступных статических конечных карт ("константных карт"), а также позволяет легко сделать "защитную копию" карты, предоставленной вашему классу вызывающей стороной.
Ответ 3
Документация Guava
JDK предоставляет методы Collections.unmodifiableXXX
, но, на наш взгляд, они могут быть громоздкими и многословными; неприятно использовать везде, где вы хотите сделать защитные копии небезопасными: возвращенные коллекции являются действительно неизменными, если никто не ссылается на исходную коллекцию неэффективно: структуры данных все еще имеют все накладные расходы на изменяемые коллекции, включая проверки параллельной модификации, дополнительное пространство в хэш-таблицы и т.д.
Ответ 4
ImmutableMap не принимает значения null
, тогда как Collections.unmodifiableMap()
делает. Кроме того, он не изменится после строительства, а UnmodifiableMap
может. Из JavaDoc:
Постоянная, ориентированная на хэш-карта с надежным пользовательским порядком итерации. Не разрешает нулевые ключи или значения.
В отличие от Collections.unmodifiableMap(java.util.Map), который является видом отдельной карты, которая все еще может измениться, экземпляр ImmutableMap содержит свои собственные данные и никогда не изменится. ImmutableMap удобен для публичных статических окончательных карт ( "постоянные карты" ), а также позволяет легко сделать "защитную копию" карты, предоставленной вашему классу вызывающим абонентом.