1. Overview
1.概述
Simply put, a Set is a collection that contains no duplicate elements. In Java, Set is an interface that extends the Collection interface.
简单地说,Set是一个不包含重复元素的集合。在Java中,Set是扩展Collection接口的一个接口。
In this quick tutorial, we’ll go through different ways of copying sets in Java.
在这个快速教程中,我们将了解Java中复制集合的不同方法。
2. Copy Constructor
2.复制构造函数
One way of copying a Set is to use the copy constructor of a Set implementation:
复制Set的一种方法是使用Set实现的copy构造函数。
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
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接口有一个addAll方法。它将集合中的元素添加到目标集合中。因此,我们可以使用addAll方法将现有集合的元素复制到一个空集合中。
Set<T> copy = new HashSet<>();
copy.addAll(original);
4. Set.clone
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.
让我们记住,Set是一个扩展了Collection接口的接口,因此我们需要引用一个实现了Set接口的对象来创建另一个Set的实例。 HashSet、TreeSet、LinkedHashSet和EnumSet都是Java中Set实现的例子。
All these Set implementations have a clone method since they all implement the Cloneable interface.
所有这些Set实现都有一个克隆方法,因为它们都实现了Cloneable接口。
So, as another approach to copying a set, we can call the set’s clone method:
因此,作为复制一个集合的另一种方法,我们可以调用该集合的clone方法。
Set<T> copy = (Set<T>) original.clone();
Let’s also 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.
我们还要注意,克隆最初来自于Object.clone。集合实现重写了Object类的clone方法。克隆的性质取决于实际的实现。例如,HashSet只做了一个浅层拷贝,尽管我们可以通过编码来实现做一个深层拷贝。
As we can see, we are forced to typecast the cloned object to Set<T> since the clone method actually returns an Object.
我们可以看到,我们被迫将克隆的对象类型化为Set<T>,因为clone方法实际上返回一个Object。
5. JSON
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.
另一种复制集合的方法是将其序列化为JSON String,并从生成的JSON String中创建一个新集合。同样值得注意的是,对于这种方法,集合中的所有元素和引用的元素都必须是可序列化的,并且我们将对所有对象进行深度复制。
In this example, we’ll copy the set by using the serialization and deserialization methods of Google’s Gson library:
在这个例子中,我们将通过使用Google的Gson 库的serialization和deserialization方法复制该集合。
Gson gson = new Gson();
String jsonStr = gson.toJson(original);
Set<T> copy = gson.fromJson(jsonStr, Set.class);
6. Apache Commons Lang
6.阿帕奇公社朗
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:
Apache Commons Lang有一个SerializationUtils类,它提供了一个特殊的方法 – clone – 可以用来克隆一个给定的对象。我们可以利用这个方法来复制一个集合。
for (T item : original) {
copy.add(SerializationUtils.clone(item));
}
Let’s note that SerializationUtils.clone expects its parameter to extend the Serializable class.
我们注意到,SerializationUtils.clone希望它的参数能够扩展Serializable class。
7. Collectors.toSet
7.Collectors.toSet
Or, we can use Java 8’s Stream API with Collectors to clone a set:
或者,我们可以使用Java 8的StreamAPI与Collectors来克隆一个集合。
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.
Stream API的一个优点是它提供了更多的便利,允许我们使用skips、filters等等。
8. Using Java 10
8.使用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:
Java 10为Set接口带来了一个新特性,允许我们从给定集合的元素中创建一个不可变的集合。
Set<T> copy = Set.copyOf(original);
Note that Set.copyOf expects a non-null parameter.
注意Set.copyOf需要一个非null参数。
9. Conclusion
9.结语
In this article, we’ve explored different ways of copying sets in Java.
在这篇文章中,我们已经探讨了在Java中复制集合的不同方法。
As always, check out the source code for our examples, including the one for Java 10.
一如既往,请查看我们的示例的源代码,包括用于Java 10的示例。