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?
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 theList<Point>
is also the exclusive owner of thePoint
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 thePoint
objects held therein, then a proper clone of theList<Point>
must hold references to copies of thePoint
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 theList<Point>
could hold references to either the originalPoint
objects or copies thereof; the former would be faster, but the latter would still be semantically correct.If the
List<Point>
serves to identifyPoint
instances which may be modified by other code, and any such modification needs to be reflected in theList<Point>
itself, then a proper clone must hold references to the samePoint
objects as the original list. If a clone were to instead hold copies of thosePoint
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.