Как получить неизменяемую коллекцию из java HashMap?

Мне нужно получить коллекцию из java HashMap без изменений на карте, отраженных в коллекции позже . Я хотел использовать коллекцию.toArray() для достижения этого, но его не работает . Результирующий объект[] также изменяется (javadocs говорят, что возвращаемый массив будет "безопасным", поскольку никакие ссылки на него не поддерживаются этой коллекцией ) . Любой простой способ достичь этого?

5 ответов


Это невозможно сделать с помощью одного вызова API, вам нужно использовать глубокое клонирование. Клоны не будут изменены при внесении изменений в оригинал. Эта тема обсуждалась на SO раньше, см. как клонировать ArrayList, а также клонировать его содержимое? и глубокая рекомендация утилиты клонирования.



вы можете создать unmodifiable карта


следующее по-прежнему верно и описывает наблюдаемую проблему (см. бит о том, какая копия выполняется). Однако я не даю никакого ответа на как для выполнения глубокой копии.

вместо мое предложение, для проектирования объектов неизменяемые, что полностью устраняет эту проблему. По моему опыту, это очень хорошо работает для большинства тривиальных объектов (то есть объектов, которые не являются "контейнерами") и может упростить код и рассуждения об этом.


из Javadoc для HashMap.values:

возвращает представление набора значений, содержащихся в этой карте. коллекция поддерживается картой, так что изменения на карте отражаются в коллекции, и наоборот...

возможно, было бы полезно создать его копию?

HashMap<K,V> map = ....;
List<V> values = new ArrayList<V>(map.values());

, что, по сути, выполняет мелкий-копия что есть "отдельно". Однако,будучи мелкая копия, клон / копия содержащихся объектов не выполняется. (См. ответ βнɛƨн ǥʋяʋиɢ, если глубокий-копия семантика желательна: сам вопрос кажется немного расплывчатым по этому вопросу.)

удачи в кодировании


создайте неглубокую копию исходной карты whith HashMap.clone(), затем извлеките из этого значения colleation. Это создаст новые ссылки на объекты в исходной карте во время clone() вызов; очевидно, что изменения внутри самих содержащихся объектов по-прежнему будут отражены в скопированной коллекции. Если вы хотите такого поведения, ваш единственный способ-скопировать объекты карты в нужную коллекцию.