2016-06-13 6 views
4

Java doc говорит, что возвращаемые значения значений метода() и entrySet() поддерживаются картой. Поэтому изменения в карте отражаются в наборе и наоборот. Я не хочу, чтобы это случилось с моей статической копией. По сути, я хочу, чтобы на моем DS выполнялось множество параллельных операций. Но в некоторых случаях я хочу повторить статический снимок. Я хочу повторить статический снимок, поскольку я предполагаю, что итерация по статическому снимку будет быстрее по сравнению с версией, которая обновляется одновременно.Java: Как сделать статический снимок ConcurrentHashMap?

+1

Вы собираетесь многократно перебирать один статический моментальный снимок или ваш план в основном 'for (final Map.Entry <..., ...> запись: takeStaticSnapshot (map)) {doStuff(); } '? (Я спрашиваю, потому что в последнем случае я не думаю, что есть какой-либо способ сделать статический снимок без явного итерации по карте в любом случае. И в * любом случае вы должны знать, что такой снимок не будет атомарным.) – ruakh

+0

Определите «моментальный снимок». Будет ли какая-либо копия, или она должна быть последовательной/атомной/точка-во-время? – Thilo

+1

«Я предполагаю, что итерация по статическому снимку будет быстрее по сравнению с версией, которая обновляется одновременно». Я бы прокомментировал это, прежде чем перейти к выводам/усилиям моментального снимка. – Thilo

ответ

1

Просто сделайте копию, новый HashMap будет независим от оригинальной.

Set<K> keySetCopy = new HashSet<>(map.keySet()); 
List<V> valuesCopy = new ArrayList<>(map.values()); 

Однако важно, что это будет иметь полную итерацию по concurrentStructure, один раз, но только тогда статические снимки. Таким образом, вам понадобится время, эквивалентное одной полной итерации.

7

Просто сделайте копию, и она не будет изменена.

Set<K> keySetCopy = new HashSet<>(map.keySet()); 
List<V> valuesCopy = new ArrayList<>(map.values()); 

Все реализации коллекции есть конструктор копирования, который будет копировать все данные о поставляемой коллекции вновь созданный, не будучи подкреплено оригиналом.

Примечание: это не будет работать с entrySet(), поскольку фактические записи в карте по-прежнему будут «принадлежать» к исходной карте, и изменения в исходных данных будут отражены в ваших копиях. Если вам нужен entrySet(), сначала скопируйте всю карту, используя ту же технику.

Set<Entry<K,V>> entrySetCopy = new HashMap<>(map).entrySet(); 

Обратите внимание, что все они требуют полной итерации Once (в конструкторе) и только тогда статические снимки. Насколько мне известно, об этом ограничении нет.

+2

Обратите внимание, что это все еще требует повторения исходной ConcurrentHashMap, поэтому может не соответствовать требованиям OP. – ruakh

+0

@SeanPatrickFlyod Спасибо. У меня было еще одно сомнение. Скажем, у меня есть ConcurrentHashMap CHM, значения которого являются объектами класса A. Таким образом, значения в CHM будут указателями объектов типа A, вызывающими один из них как p. Поэтому, если я сделаю копию CHM.values ​​() в ArrayList AL. AL будет содержать p. Теперь, если я внес изменения в свойство объекта p, обратитесь к. Это будет отражено, когда я получу доступ к нему позже из CHM. Правильно? – PHcoDer

+1

Да, общие объекты являются общими, поэтому изменения будут отображаться как на исходной карте, так и на снимке (по модулю поперечного распространения). – Thilo