Deep Copy, Shallow Copy, Clone

What is the difference between a deep copy and a shallow copy?

Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements.

Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.

Java: Why String is special in Deep Copy and Shallow copy?

You start with this situation:

Sample Image

Then you clone the User object. You now have two User objects; the variables user and clone refer to those two objects. Note that both their name member variables refer to the same String object, with the content "one".

Sample Image

Then you call setName("two") on clone, which will change the name member variable of the second User object to refer to a different String object, with the content "two".

Sample Image

Note that the variable user still refers to the User object which has its name member variable referring to "one", so when you System.out.println(user.getName()); the result is one.

Shallow copy or Deep copy?

From the link here

Shallow copies duplicate as little as possible. A shallow copy of a
collection is a copy of the collection structure, not the elements.
With a shallow copy, two collections now share the individual
elements.

Deep copies duplicate everything. A deep copy of a collection is two
collections with all of the elements in the original collection
duplicated.

Your example is creating a shallow copy.

A ob1 = new A();
ob1.a = 10;
A ob2 = new A();
ob2 = ob1;

ob1.a = 5; // <-- If you see value of ob2.a after this line, it will be 5.

Deep copy will be -

 A ob1 = new A();
ob1.a = 10;
A ob2 = new A();
ob2.a = ob1.a;

ob1.a = 5; // <-- If you see value of ob2.a after this line, it will be 10.

What is better shallow or deep cloning?

In shallow cloning, cloned class doesn't copy its internal objects but in deep cloning all internal objects of the class are also copied.
One disadvantage of deep cloning that seem is with serialization, that serialization of such cloned object is not that easier.

However it can not be said which is better.

ES6 React - What are the difference between reference, shallow copy and deep copy and how to compare them?

Let's consider the example below

clone and clone2 are shallow, only properties of original object are affected. clone3 and clone4 are deep.

However if the spread operator only creates deep copy sometimes, then how can I test if the new object is a deep copy or not?

It creates deep copy in case of clone4 - as long as the depth is controlled by a developer. Generally there's no need to test if an object is deep copy or just different in React, because this check is expensive and requires to traverse nested objects in both compared objects and compare them property by property.

Performance is the reason why React relies on immutability. If a new value isn't === equal, it's considered a different value.

So james is a shallow copy in Facebook's code.

It isn't. It's a reference that was assigned to another variable. It's still same object.

Are reference and shallow copy exactly the same thing in JS?

A reference isn't a copy. So it isn't shallow copy, too.

I commented NBAChampion out in clone4, so now NBAChampion is a reference rather than copy! If I push a new value in user.highlights.NBAChampion, clone4 will also updates.
What should we call this type of object? It's neither a shallow nor deep copy.

It's just a copy. It doesn't have specific name, because there's rarely a need to do such selective copies. If the intention is to make it act like deep copy, it should be called a mistake.

In Java, what is a shallow copy?

A shallow copy just copies the values of the references in the class. A deep copy copies the values. given:

class Foo {
private Bar myBar;
...
public Foo shallowCopy() {
Foo newFoo = new Foo();
newFoo.myBar = myBar;
return newFoo;
}

public Foo deepCopy() {
Foo newFoo = new Foo();
newFoo.myBar = myBar.clone(); //or new Bar(myBar) or myBar.deepCopy or ...
return newFoo;
}
}

Foo myFoo = new Foo();
Foo sFoo = myFoo.shallowCopy();
Foo dFoo = myFoo.deepCopy();

myFoo.myBar == sFoo.myBar => true
myFoo.myBar.equals(sFoo.myBar) => true
myFoo.myBar == dFoo.myBar => **false**
myFoo.myBar.equals(dFoo.myBar) => true

In this case the shallow copy has the same reference (==) and the deep copy only has an equivalent reference (.equals()).

If a change is made to the value of a shallowly copied reference, then the copy reflects that change because it shares the same reference. If a change is made to the value of a deeply copied reference, then the copy does not reflect that change because it does not share the same reference.

C-ism

int a = 10; //init
int& b = a; //shallow - copies REFERENCE
int c = a; //deep - copies VALUE
++a;

Result:

a is 11  
*b is 11
c is 10


Related Topics



Leave a reply



Submit