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 .