Перейти к основному содержимому

Копирование наборов в Java

· 3 мин. чтения

1. Обзор

Проще говоря, Set — это коллекция, не содержащая повторяющихся элементов. В Java Set — это интерфейс, расширяющий интерфейс Collection .

В этом кратком руководстве мы рассмотрим различные способы копирования наборов в Java.

2. Конструктор копирования

Одним из способов копирования Set является использование конструктора копирования реализации Set :

Set<T> copy = new HashSet<>(original);

Конструктор копирования — это особый тип конструктора, который используется для создания нового объекта путем копирования существующего объекта .

Здесь мы на самом деле не клонируем элементы данного набора. Мы просто копируем ссылки на объекты в новый набор. По этой причине каждое изменение, сделанное в одном элементе, повлияет на оба набора.

3. Установить.добавитьвсе

Интерфейс Set имеет метод addAll . Он добавляет элементы коллекции в целевой набор. Поэтому мы можем использовать метод addAll для копирования элементов существующего набора в пустой набор:

Set<T> copy = new HashSet<>();
copy.addAll(original);

4. Установить клон

Давайте помнить, что Set — это интерфейс, расширяющий интерфейс Collection , поэтому нам нужно обратиться к объекту, который реализует интерфейс Set , чтобы создать еще один экземпляр Set . HashSet , TreeSet , LinkedHashSet и EnumSet — все это примеры реализации Set в Java.

Все эти реализации Set имеют метод clone, поскольку все они реализуют интерфейс Cloneable .

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

Set<T> copy = (Set<T>) original.clone();

Отметим также, что клонирование изначально происходит из Object.clone . Реализации набора переопределяют метод клонирования класса Object . Характер клона зависит от фактической реализации. Например, HashSet выполняет только поверхностную копию, хотя мы можем закодировать способ сделать глубокую копию .

Как мы видим, мы вынуждены привести клонированный объект к типу Set<T> , так как метод clone на самом деле возвращает Object .

5. JSON

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

В этом примере мы скопируем набор, используя методы сериализации и десериализации библиотеки Google Gson :

Gson gson = new Gson();
String jsonStr = gson.toJson(original);
Set<T> copy = gson.fromJson(jsonStr, Set.class);

6. Язык Apache Commons

В Apache Commons Lang есть класс SerializationUtils , предоставляющий специальный метод — clone — который можно использовать для клонирования заданного объекта. Мы можем использовать этот метод для копирования набора:

for (T item : original) {
copy.add(SerializationUtils.clone(item));
}

Заметим, что SerializationUtils.clone ожидает, что его параметр будет расширять класс Serializable .

7. Коллекторы.toSet

Или мы можем использовать Stream API Java 8 `` с коллекторами для клонирования набора:

Set<T> copy = original.stream()
.collect(Collectors.toSet());

Одним из преимуществ Stream API является то, что он обеспечивает большее удобство, позволяя нам использовать пропуски , фильтры и многое другое.

8. Использование Java 10

Java 10 привносит новую функцию в интерфейс Set , которая позволяет нам создавать неизменяемый набор из элементов данной коллекции :

Set<T> copy = Set.copyOf(original);

Обратите внимание, что Set.copyOf ожидает ненулевой параметр.

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

В этой статье мы рассмотрели различные способы копирования наборов в Java.

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