Sunday, 20 March 2016

java - Is shallow copy really needed?



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 and that itself can contain anything.

(I know this might be redundant and i could just do Vertex but for the purpose of the question it doesn't matter).

I made VertexData implement Cloneable and have a public VertexData 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 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?


Answer



A container type like List 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 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 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 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 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 serves to identify Point instances which may be modified by other code, and any such modification needs to be reflected in the List 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.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...