`What's the 'canonical table?I can't find any description of it.Can anyone provide a example?'
Are you reading Java Performance Tuning? I saw those concepts in there.
A canonical object means an object with a single reference pointed to it, with no copies holding the same state possible.
The activity of replacing multiple copies of an object with just a few objects is often referred to as canonicalizing objects.
For example Boolean, could have been canocalized, but it were not because new objects can be created with new, thus it's possible to create more than one instance with the same state.
A Canonical Lookup Table is some sort of cache containing references to those canonical object pool.
Related
We're using a recursion that iterates through tree nodes and does some computation that is a logical equivalent of something as
public static Result iterate(TreeNode node, Dictionary dictionary ) {
Map<String, Result> accumulated = new HashMap<String, Result>();
for (TreeNode child : node.getChildren()) {
Result partialResult = iterate(child, dictionary);
accumulated.put(child.getId(), partialResult);
}
return completeResult(accumulated);
}
Now the Dicitionary object is not mutated while the recursion is being done. Its simply used as a lookup table. The object is in fact quite big.
Does the fact that we have the dictionary as an argument of our recursive call have a negative impact on the memory/performance? Is this a bad design?
The really interesting issue is: "How is the Dictionary related to the Tree?"
If several Dictionaries need to be used with different iterations, you would indeed pass a Dictionary as a parameter to the iterate method, as you have it right now. (But why it "iterate" static?)
If a Dictionary is a stable property associated with some specific Tree object, its reference should be passed to the constructor and stored as an instance field. The iterate being a method could access it as any other instance field.
Possibly the Dictionary is universal and unique for all Tree objects? Then you might advocate setting the Dictionary as a static class field, and your iterate method would access it as a "global".
Technically, all of the above just passes a reference ("address") around; no copying of a potentially huge object is involved...
I would say your design is correct, in that it should produce correct results. For its performance, you would really need to do some thorough testing to assess, with various combinations of sizes for your tree structure and dictionary. Also, the implementation of Dictionary will probably play a major role in the performance characteristics.
Memory-wise, your current implementation should be the most economical, as you use the existing structures, instead of copying to others, in order to use a faster algorithm.
Passing the dictionary as an argument has the benefit of isolating each recursive run, in the case that the dictionary can change between runs, and provided that you copy the dictionary for each run. Also, it gives you the capability of using the same code to do concurrent searches (using threads) on different trees using different dictionaries. Using a global dictionary wouldn't allow you to do this.
I think this question boils down to whether Java passes by reference or value. Somewhat confusingly Java always passes by value, but where an object is passed the value is the object reference.
So for your example the method iterate takes a parameter Dictionary dictionary. The internals of this object will be stored on the heap. This is an area of memory that is shared among all objects. Additionally your method will have it's own unique reference on the stack. The reference acts as a kind of pointer so your method can lookup the values of dictionary.
When you make the recursive call the JVM will make a new reference to the same dictionary object and put this reference on the stack for the new method call. So now you have two calls to iterate on the call stack, both with their own individual reference to the dictionary object, but only one actual dictionary object on the heap.
If you were to make changes to the dictionary object using either reference it would update the same underlying object so both methods would see these changes.
When the method returns, since the dictionary reference is local to the method it will be removed from the stack. This will reduce the reference count to this object by 1. If the total number of references reaches 0 then your object becomes eligible for garbage collection since nothing will be able to see it.
Back to your question about memory I don't think you need to worry. It's the object on the heap where all of the data will be. References are cheap by comparison (8 bytes for a Java reference). Each reference will in theory take up a little memory but you are only likely to hit problems if your recursive loop doesn't exit.
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 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.
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.
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:
shallow copy can lead to unwanted effects if the elements of values are changed from other reference.
deep copy:
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.
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?
I am facing a small problem with Java ArrayList and singleton Object.
I collected some data and put them to this singleton Object and put it into the ArrayList. I need to know, will it refer to the original Object or get a copy of that Singleton Object. I need to get separate copies to put in ArrayList.
Explain in detail...
An ArrayList contains references to objects. Whatever references you put in the ArrayList, those references will be stored in there. For example, if you put 10 references (say r1, r2, ..., r10) which point to the same object, then you'll have an ArrayList of size 10 but all its members will point to the same object. This is how this works. So don't get confused, the ArrayList knows nothing about whether your objects are singletons or not, it deals just with storing references to objects.
The list will store an original reference to your singleton.
I don'get it why you are going to get copies of singleton. This is not how a singleton works.
When I read about "In How many ways we can create an Object in java".
I found four way:
Creation of Object using new Operator.
Cloning
Serialization
Reflection.
With new and reflection, I am fine with these two methods.
My Question is:
Why do people consider cloning and serialization as different ways of creating an Object?
The very important point here is that in object deserialization there is no constructor involved in the process -- that's why it is a distinct way to create an object. This is also true of cloning -- the method Object.clone creates a new object by JVM magic, again not involving any constructors. There is in fact much greater difference between these two ways on the one hand and new and reflection on the other, since reflection is just a slightly different way to invoke the plain-vanilla object instantiation involving a specific constructor.
When you clone an object, that means that you are dealing with something that lies in a different part of memory from the original object. Yes, they might have the same properties, but they are two different pointers with two different blocks of memory.
When you unserialize an object then an object exists which did not exist before. Even if you serialize and then immediately unserialize, it will exist independently from the original object.
Put another way, you create a new kind of object by making a package containing existing objects. Thus, you can build complexity into a program while hiding it behind the simplicity of objects.
from Thinking in Java
Are not all objects independent of each other in Java? Is it possible to create a super object from different objects?
EDIT:
Alan Kay summarized five basic characteristics of Smalltalk way before Java was around. This is one of the characteristics of an OOP according to him. I was wondering if it is still valid for java.
I think you have to distinguish two separate concepts:
In memory each object in Java is a separate entity with its own set of memory (and I believe Smalltalk worked the same way). It can reference other objects, which are held in their own memory, but not "contain" other objects within its memory.
Conceptually, there are objects that "belong" to other objects in some way. For example the char[] holding the data of a String is technically a separate object, but the only other object referencing it is the String (and possibly other String instances, but let's ignore that at the moment). In this sense, the String contains the char[].
An object can't contain other objects directly in Java - but it can certainly hold references to other objects. I suspect that's what the author is trying to get across.
So if a Customer object knows about the address, phone number, list of orders, name etc, those would all be separate objects... but instead of having to manage all of those explicitly, the user of a Customer object just keeps a reference to the object, and accesses the rest of the data via that single object.