Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How to deep-clone a HashSet neatly?

Tags:

java

cloning

I have a HashSet of MyObject that I need to clone. If MyObject implements a copy-constructor, what is the easiest, neatest way to clone Set myObjects

Obviously I could do something like:

 Set<MyObject> myNewObjects = new Set<MyObject>(); 
 for(MyObject obj: myObjects) myNewObjects.add(new MyObject(obj));

But I'm doing this as part of a loooong copy-construcotr, and I'd really like to just be able to do it in one line like:

public myClass(MyClass toClone){
    //... 
    this.myObjects = new Set<MyObjects>(toClone.getmyObjects()); 
    //... 
}

Any suggestions?

like image 247
Paul Avatar asked Jun 26 '14 17:06

Paul


People also ask

Can a HashSet be cloned?

HashSet. clone() method is used to return a shallow copy of the mentioned hash set. It just creates a copy of the set. Parameters: The method does not take any parameters.

How can you achieve the deep cloning of an object by random access?

To achieve a deep copy, we can serialize an object and then deserialize it to a new object.

Is clone Java deep copy or shallow copy?

The default implementation of Java Object clone() method is using shallow copy. It's using reflection API to create the copy of the instance.

What is the difference between deep copy and shallow copy?

In Shallow copy, a copy of the original object is stored and only the reference address is finally copied. In Deep copy, the copy of the original object and the repetitive copies both are stored.


2 Answers

If you are using Java 8, you can do something like this:

Set<MyObject> set1 = new HashSet<>();
Set<MyObject> set2 = set1.stream().map(MyObject::new).collect(Collectors.toSet());

Keep in mind, however, that using Collectors.toSet():

There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned

Although current implementation in Java 8 Update 5 uses regular HashSet.

like image 95
izstas Avatar answered Oct 27 '22 06:10

izstas


You can use Google Guava's Iterables to do something like this:

Set<MyObject> newSet = new HashSet<MyObject>(
  Iterables.transform(myObjects,new Function<MyObject, MyObject>() {
    @Override
    public MyObject apply(MyObject input) {
      return new MyObject(input);
    }
  }));

Or if you want it immutable use Guava's immutable set:

Set<MyObject> newSet = ImmutableSet.copyOf(
  Iterables.transform(myObjects,new Function<MyObject, MyObject>() {
    @Override
    public MyObject apply(MyObject input) {
      return new MyObject(input);
    }
  }));

Unfortunately it does not get any more compact than what you already have unless you can use Java 8.

like image 30
Giovanni Botta Avatar answered Oct 27 '22 08:10

Giovanni Botta