Is shallow copy really needed?

2.8k views Asked by At

I am currently working on a graphs library for Java. As you expect there exists a Vertex class. That class contains an object of typeVertexData<T> and that itself can contain anything.
(I know this might be redundant and i could just do Vertex<T> but for the purpose of the question it doesn't matter).
I made VertexData<T> implement Cloneable and have a public VertexData<T> clone() method returning a deep copy by serializing and deserializing the calling Object, pretty much like described here

Now the question is, since i do have a deep copy method, does it make sense to also have a shallow copy? If so what is a case that a shallow copy would be preferred over a deep copy?

UPDATE: Since most of the answers and comments include some explanation of what a shallow copy is in one way or another, i feel like that i have to clarify a bit. I do know what a shallow copy is, how it works, everything. My question is that since it is a library that i am developing, and since i do have created a deep copy method, does it make sense to also make available a method for shallow copy?

I will add here too that there are no primitive types contained in VertexData<T> class.
So in the context of a container class used to store Vertex data for a graph library, will a shallow copy ever be needed?
If so can you think of an example, within the context of what i am developing?
If not should i add a shallow copy method only for the sake of completeness?
Is that a good practice or does it not matter?

4

There are 4 answers

0
supercat On BEST ANSWER

A container type like List<Point> may in some cases be used to hold a bunch of X,Y coordinate pairs, but in other cases may be used to identify a bunch of movable points which are used by other code. The former case may be subdivided into subcases where the owner of the List<Point> is also the exclusive owner of the Point instances therein and may modify them at will, or where the owner will never modify those instances but may share references to them with code that promises not to modify them either.

If the List<Point> is used to encapsulate (X,Y) coordinate pairs, but the the owner might modify the Point objects held therein, then a proper clone of the List<Point> must hold references to copies of the Point objects in question. If it encapsulates coordinate pairs, but nobody will ever modify the objects therein (and recipients of a cloned list wouldn't expose references to the objects therein to any code that might modify them) then a proper clone of the List<Point> could hold references to either the original Point objects or copies thereof; the former would be faster, but the latter would still be semantically correct.

If the List<Point> serves to identify Point instances which may be modified by other code, and any such modification needs to be reflected in the List<Point> itself, then a proper clone must hold references to the same Point objects as the original list. If a clone were to instead hold copies of those Point objects, then it would no longer hold the same semantic information as the original list.

If Java had segregated collection types based upon whether they encapsulate value using exclusively owned mutable instances or shareable immutable instances, or whether they serve to identify the things therein, then it would be possible to have a single concept of "cloning", rather than requiring "deep" and "shallow" cloning. Without such a distinction between collection types, however, it's necessary to have cloning methods which can do whatever will be needed based upon the things in the collection.

3
zookastos On

You will not need a shallow copy. A shallow copy will just assign a new reference variable to your already existing object in memory. An '=' operator will do the work. For more details, please go through this post - In Java, what is a shallow copy?

0
Adam On

It really comes down to requirements. Knowing your object has more than primitive fields alone, it should (and thankfully does) have a deep copy. There is no "hard and fast rule" with whether to use shallow or deep. Since it is "based on requirement", it would be safe to provide both as @RyanJ points out in a comment to another answer.

If you wish to shallow copy your collection or object, and make a change to one attribute, it will change both the reference as well as the copied object. On the other hand, if you wish to deep copy and be able to change values of an object or the copy of the object and NOT have it affect both the copy and original, deep copy is all you need. It all comes down to requirement and what you need your object/system to do. My final recommendation is to do both.

0
Tejus Prasad On

Yes it is required in few cases. you can infer the requirement based on the following points.

if the object has only primitive fields, then you should go for shallow copy.

if the object has references to other objects, then based on the requirement, you should consider shallow copy or deep copy.

if the references are not modified then its not required to do deep copy. here u should go for shallow copy.

if the references are modified then deep copy is preferred.

shallow copy:

enter image description here

shallow copy can lead to unwanted effects if the elements of values are changed from other reference.

deep copy:

enter image description here

during deep copy any Changes to the array values refers to will not result in changes to the array data refers to.

u can refer to this link to understand more about this with examples.