Мне нужно получить коллекцию из java HashMap без изменений в карте, отражающихся в коллекции позже. Я хотел использовать Collection.toArray () для этого, но он не работает. Результирующий Object [] также изменяется (в javadocs сказано, что возвращенный массив будет «безопасным», поскольку эта коллекция не поддерживает никаких ссылок на него). Любой простой способ добиться этого?
Как получить неизменяемую коллекцию из java HashMap?
Ответы (5)
Это невозможно сделать с помощью одного вызова API, вам нужно использовать глубокое клонирование. Клоны не будут изменены, когда вы внесете изменения в оригинал. Эта тема ранее обсуждалась на SO, см. Как клонировать ArrayList а также клонировать его содержимое? и Рекомендации утилиты глубокого клонирования.
Неизменяемая карта коллекций Google может помочь тебе.
см. Collections.unmodifiableMap также
K
(единственный способ добиться этого в Java - добавить копию / клон объектов типа K). Он утверждает, что он отличается от unmodifiableMap
, который вызовет исключение put
, но по-прежнему будет показывать новые ключи через keys
(например), если исходная (резервная) карта модифицирован; в документации звучит так, будто это разница.
- person ; 28.01.2012
Вы можете создать неизменяемый Карта
unmodifiableMap
вернет доступное только для чтения представление карты, которое отразит любые изменения в базовом контейнере, а sanre6 не указал, что содержащиеся объекты должны быть неизменяемыми, только то, что карта должна быть.
- person Francois; 28.01.2012
Следующее по-прежнему актуально и описывает наблюдаемую проблему (см. Бит о том, какой тип копирования выполняется). Однако я не отвечаю на вопрос, как выполнять глубокое копирование.
Вместо этого мое предложение состоит в том, чтобы проектировать объекты так, чтобы они были неизменяемыми em>, что полностью устраняет эту проблему. По моему опыту, это очень хорошо работает для большинства тривиальных объектов (то есть объектов, которые не являются «контейнерами») и может упростить код и рассуждения по этому поводу.
Из документации Javadoc для _1 _ а>:
Возвращает представление коллекции значений, содержащихся на этой карте. Коллекция поддерживается картой, поэтому изменения на карте отражаются в коллекции, и наоборот ...
Может быть, было бы полезно создать его копию?
HashMap<K,V> map = ....;
List<V> values = new ArrayList<V>(map.values());
Это, по сути, выполняет мелкую копию, которая «теперь отделена». Однако, будучи неглубокой копией, клонирование / копирование содержащихся объектов не выполняется. (См. Ответ βнɛƨн Ǥʋяʋиɢ, если требуется семантика глубокой копии: сам вопрос кажется немного расплывчато по этому поводу.)
Удачного кодирования
Создайте неглубокую копию исходной карты с HashMap.clone()
, затем извлеките из нее коллекцию значений. Это создаст новые ссылки на объекты исходной карты во время вызова clone()
; очевидно, что изменения внутри самих содержащихся объектов по-прежнему будут отражаться в скопированной коллекции. Если вы хотите такого поведения, единственный способ - это скопировать объекты карты в желаемую коллекцию на бумажном носителе.