2015-06-19 2 views
1

У меня есть 2 HashMap следующим образом:копия карты на другую новую карту

@Session 
private Map< Integer, List<ObjectA>> keyMap; 

@Session 
private Map< Integer, List<ObjectA>> keyMap2; 

Сначала я положил некоторые данные в keyMap, а затем я пытаюсь сохранить данные в keyMap для keyMap2:

keyMap2 = keyMap; 

И затем, я отредактирую некоторые данные внутри keyMap. Однако значение внутри keyMap2 изменится как то, что я отредактировал в keyMap.

Как я пониманию, это потому, что keyMap2 только точка keyMap указатель, так что-то изменить в keyMap, он будет отражать в keyMap2, так же указателю. (Пожалуйста, исправьте меня, если я ошибаюсь.)

Я хочу сохранить значение keyMap2 без изменений, например keyMap. Любую идею, отличную от петли я keyMap, и поставьте 1 на 1 внутри keyMap2.

+1

'keyMap2 = новый HashMap <> (KEYMAP) '. – saka1029

+0

привет @ saka1029, это не работает для меня. Я думаю, может быть, мой HashMap содержит список внутри. I и внести изменения в список для 'keyMap' –

ответ

0

Отредактировано: как указано в комментарии, оригинальный подход не будет работать из-за копирования содержащегося списка по ссылке.

Если подход с использованием Java8 потоков не работает еще одна возможность будет итерация по карте с:

for (keyMap.Entry<Integer, List<ObjectA>> entry : map.entrySet()) { 
    //Code 
} 

Вы можете скопировать содержимое в keyMap2 с помощью entry.getKey() и неглубокую или глубокую копию списка из entry.getValue()

Если требуется неполная копия (копия ObjectA по ссылке), то new ArrayList<ObjectA>(entry.getValue()) должен работать, но для глубокой копии (нужны новые экземпляры ObjectA) необходима дополнительная информация об объекте.


Оригинал:

Вам нужно скопировать HashMap в полном объеме.

Это покрыто: copying a java hashmap

private Map< Integer, List<ObjectA>> keyMap2 = new HashMap< Integer, List<ObjectA>>(keyMap); В сущности

Или же keyMap2.addAll(keyMap);

+0

Интерфейс карты действительно предлагает метод putAll, не так ли? – skypjack

+0

Привет, это не работает для меня.'keyMap2.clear();' 'keyMap2.putAll (serviceAccountsKeyMap);' значение 'keyMap2' все равно изменяется, если я изменяю значение внутри' keyMap' –

+0

Подождите, вы меняете содержимое keyMap или свойства какого-либо объекта, который содержится в этой карте? В последнем случае вы все еще страдаете проблемой сглаживания ... – skypjack

0

Проблема вы натыкался называется ступенчатость.

Для того, чтобы разбить его на вашем случае, вы должны:

  • определяют метод clone на классе ObjectA
  • итерацию по keySet первой карте, таким образом:
    • получить экземпляр List, связанный с конкретным ключом
    • создать новый экземпляр этого списка
    • итерации над бывшим, клонировать содержащиеся элементы и поместить их в последнем
    • поставить новый список во второй карте, наряду с ключом, используемым для получения исходного списка

Таким образом, вы создаете с нуля новый список и полный набор элементов, которые равны исходным по содержанию, но не являются одними и теми же объектами в памяти.

+0

Привет, это не работает для меня. 'keyMap2.clear();' 'keyMap2.putAll (serviceAccountsKeyMap);' Значение 'keyMap2' все равно изменяется, если я изменяю значение внутри' keyMap' –

0

Как вы правильно сказали, keyMap2 указывает на то же HashMap, как keyMap

Но если вы делаете:

keyMap2 = (HashMap<String, String>) keyMap.clone(); 

Это позволит сделать копию keyMap и точку keyMap2 к этой копии. Любые изменения в keyMap дальнейшем не будет отражать в копии

Это позволит решить вашу проблему

0

В Java нет таких вещей, как указатели. Используйте (используйте для этого C \ C++), чтобы ваши изменения не отражались. Вы можете использовать:

keyMap2 = (HashMap<String, String>) keyMap.clone(); 

Или:

keyMap.putAll(keyMap2) //This will add all the keys in "keymap" to "keymap2" 
//Source: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html 

Опять же, эти изменения не будут отражать, потому что нет в Java нет pointers.

Cheers.

0

Вы можете копировать, используя Java 8 Stream, как это.

Map<String, List<ObjectA>> keyMap2 = keyMap.entrySet().stream() 
     .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), new ArrayList<>(e.getValue()))) 
     .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); 

Этот код копирует списки значений keyMap.

0

Использование Java 8 потока и ссылки на метод:

Map<Integer, List<ObjectA>> keyMap2 = keyMap.entrySet().stream() 
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 

Или, если вы хотите, чтобы скопировать список в раскладку, а в другой список, то

Map<Integer, List<ObjectA>> keyMap2 = keyMap.entrySet().stream() 
        .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArrayList<ObjectA>(e.getValue())));