1. Overview
A Set is a collection that contains no duplicate elements. In Java, Set is an interface that extends the Collection interface.
In this tutorial, we’ll go through different ways of copying sets in Java.
2. Copy Constructor
One way of copying a Set is to use the copy constructor of a Set implementation:
Set<T> copy = new HashSet<>(original);
A copy constructor is a special type of constructor that is used to create a new object by copying an existing object.
Here, we’re not really cloning the elements of the given set. We’re just copying the object references into the new set. For that reason, each change made in one element will affect both sets.
3. Set.addAll
The Set interface has an addAll method. It adds the elements in the collection to the target set. Therefore, we can use the addAll method to copy the elements of an existing set to an empty set:
Set<T> copy = new HashSet<>(); copy.addAll(original);
4. Set.clone
Let’s keep in mind that Set is an interface that extends the Collection interface, therefore we need to refer to an object that implements the Set interface to create another instance of a Set. HashSet, TreeSet, LinkedHashSet, and EnumSet are all examples of Set implementations in Java.
All these Set implementations have a clone method since they all implement the Cloneable interface.
So, as another approach to copying a set, we can call the set’s clone method:
Set<T> copy = (Set<T>) original.clone();
Let’s note that cloning originally comes from the Object.clone. Set implementations override the clone method of the Object class. The nature of the clone depends on the actual implementation. For example, HashSet does only a shallow copy, though we can code our way to doing a deep copy.
As we can see, we are forced to typecast the cloned object to Set<T> since the clone method actually returns an Object.
5. JSON
Another approach to copy a set is to serialize it into a JSON String and create a new set from the generated JSON String. It’s also worth to note that for this approach all the elements in the set and referenced elements must be serializable and that we’ll be performing a deep copy of all the objects.
In this example, we’ll copy the set by using the serialization and deserialization methods of Google’s Gson library:
Gson gson = new Gson(); String jsonStr = gson.toJson(original); Set<T> copy = gson.fromJson(jsonStr, Set.class);
6. Apache Commons Lang
Apache Commons Lang has a class SerializationUtils that provides a special method – clone – that can be used to clone a given object. We can make use of this method to copy a set:
for (T item : original) { copy.add(SerializationUtils.clone(item)); }
Let’s note that SerializationUtils.clone expects its parameter to extend the Serializable class.
7. Collectors.toSet
Or, we can use Java 8’s Stream API with Collectors to clone a set:
Set<T> copy = original.stream() .collect(Collectors.toSet());
One advantage of the Stream API is that it provides more convenience by allowing us to use skips, filters, and more.
8. Using Java 10
Java 10 brings a new feature into the Set interface that allows us to create an immutable set from the elements of a given collection:
Set<T> copy = Set.copyOf(original);
Note that Set.copyOf expects a non-null parameter.
9. Conclusion
In this quick tutorial, we’ve explored different ways of copying sets in Java.
As always, check out the source code for our examples, including the one for Java 10.