Рубрики
Без рубрики

Копирование хэш-карты в Java

Изучите различные методы создания неглубоких и глубоких копий хэш-карты Java

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы рассмотрим концепцию неглубокой vs глубокой копии | HashMap | вместе с несколькими методами копирования HashMap в Java.

Мы также рассмотрим некоторые внешние библиотеки, которые могут помочь нам в конкретных случаях.

2. Неглубокие и глубокие копии

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

2.1. Мелкая копия

Неглубокая копия Хэш-карта это новый Хэш-карта с сопоставлениями с теми же объектами ключей и значений, что и оригинал Хэш-карта .

Например, мы создадим класс Employee , а затем карту с экземплярами Employee в качестве значений:

public class Employee {
    private String name;

    // constructor, getters and setters
}
HashMap map = new HashMap<>();
Employee emp1 = new Employee("John");
Employee emp2 = new Employee("Norman");
map.put("emp1", emp1);
map.put("emp2", emp2);

Теперь мы проверим, что исходная карта и ее неглубокая копия являются разными объектами:

HashMap shallowCopy = // shallow copy implementation
assertThat(shallowCopy).isNotSameAs(map);

Поскольку это неглубокая копия, если мы изменим свойства экземпляра Employee , это повлияет как на исходную карту, так и на ее неглубокую копию:

emp1.setFirstName("Johny");
assertThat(shallowCopy.get("emp1")).isEqualTo(map.get("emp1"));

2.2. Глубокое копирование

Глубокая копия HashMap – это новая HashMap , которая глубоко копирует все сопоставления. Поэтому он создает новые объекты для всех ключей, значений и сопоставлений.

Здесь явное изменение сопоставлений (значений ключей) не повлияет на глубокую копию:

HashMap deepCopy = // deep copy implementation

emp1.setFirstName("Johny");

assertThat(deepCopy.get("emp1")).isNotEqualTo(map.get("emp1"));

3. API HashMap

3.1. Использование конструктора HashMap

HashMap параметризованный конструктор HashMap(Map extends K,? extends V> m) обеспечивает быстрый способ быстрого копирования всей карты: extends K,? extends V> m)

HashMap shallowCopy = new HashMap(originalMap);

3.2. Использование Map.clone()

Подобно конструктору, метод HashMap # clone также создает быструю неглубокую копию:

HashMap shallowCopy = originalMap.clone();

3.3. Использование Map.put()

HashMap можно легко скопировать, выполнив итерацию по каждой записи и вызвав метод put() на другой карте:

HashMap shallowCopy = new HashMap();
Set> entries = originalMap.entrySet();
for (Map.Entry mapEntry : entries) {
    shallowCopy.put(mapEntry.getKey(), mapEntry.getValue());
}

3.4. Использование Map.putAll()

Вместо того, чтобы перебирать все записи, мы можем использовать метод putAll () , который копирует все сопоставления за один шаг:

HashMap shallowCopy = new HashMap<>();
shallowCopy.putAll(originalMap);    

Следует отметить, что put() и putAll() заменяют значения, если есть соответствующий ключ .

Также интересно отметить, что, если мы посмотрим на конструктор HashMap , clone () и putAll() реализации, мы обнаружим, что все они используют один и тот же внутренний метод для копирования записей — putMapEntries() .

4. Копирование хэш-карты с помощью API потока Java 8

Мы можем использовать Java 8 Stream API для создания неглубокой копии HashMap :

Set> entries = originalMap.entrySet();
HashMap shallowCopy = (HashMap) entries.stream()
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

5. Google Гуава

Используя Guava Maps, мы можем легко создавать неизменяемые карты, а также отсортированное и растровое изображение. Чтобы сделать неизменяемую неглубокую копию любой из этих карт, мы можем использовать метод copyOf :

Map map = ImmutableMap.builder()
  .put("emp1",emp1)
  .put("emp2",emp2)
  .build();
Map shallowCopy = ImmutableMap.copyOf(map);
    
assertThat(shallowCopy).isSameAs(map);

6. Apache Commons Lang

Теперь в Java нет встроенных реализаций глубокого копирования. Таким образом, чтобы сделать глубокую копию, мы можем либо переопределить метод clone () , либо использовать метод сериализации-десериализации.

Apache Commons имеет SerializationUtils с методом clone() для создания глубокой копии. Для этого любой класс, который будет включен в deep copy, должен реализовать Сериализуемый интерфейс:

public class Employee implements Serializable {
    // implementation details
}

HashMap deepCopy = SerializationUtils.clone(originalMap);

7. Заключение

В этом кратком руководстве мы рассмотрели различные методы копирования HashMap в Java, а также концепцию неглубокого и глубокого копирования для HashMap s.

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

Полный исходный код этих реализаций вместе с модульными тестами доступен в проекте GitHub .