aspose file tools*
The moose likes Beginning Java and the fly likes Question about clone a Hashtable Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Question about clone a Hashtable" Watch "Question about clone a Hashtable" New topic
Author

Question about clone a Hashtable

George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Hello everyone,


I want to clone the content of a Hashtable (its keys, its values and its key-value relationship). But I have found that the clone method can not completely clone a Hashtable, as is mentioned in the description of clone method of Java API Specification,

Creates a shallow copy of this hashtable. All the structure of the hashtable itself is copied, but the keys and values are not cloned. This is a relatively expensive operation.

I am wondering what is the efficient and effective approach of cloning a Hashtable, including the clone of its keys, its values and its key-value relationship.


Thanks in advance,
George
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 30762
    
156

George,
You can loop through the set of keys in the HashTable. For each one, get the associated value. Then clone the key/value and put them in a new HashTable.


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Serialize the HashTable then deserialize it into a new Object. That's the only way I know with out having to iterate cloning every item.
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Edwin,


Originally posted by Edwin Dalorzo:
Serialize the HashTable then deserialize it into a new Object. That's the only way I know with out having to iterate cloning every item.


I am very interested in this method. I am wondering whether all the keys and values are needed to be serializable if I want to use your method. Are the relationship (reference) of the objects unaffected?

It is highly appreciated if you could provide some sample source codes about your method. :-)


regards,
George
[ May 15, 2005: Message edited by: George Lin ]
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Jeanne,


Originally posted by Jeanne Boyarsky:
George,
You can loop through the set of keys in the HashTable. For each one, get the associated value. Then clone the key/value and put them in a new HashTable.


I have written a simple sample below, but from the sample's output, I have found out that it seems that the clone method of Hashtable copies the the content of both keys and values, not as mentioned in the Java API specification of clone method of class Hashtable "but the keys and values are not cloned".

Do you know what points do the Java specification mean?



Output is:

Contains!
New value1 of table1: value1
New value1 of table2: value2


regards,
George
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

I have written a simple sample below, but from the sample's output, I have found out that it seems that the clone method of Hashtable copies the the content of both keys and values, not as mentioned in the Java API specification of clone method of class Hashtable "but the keys and values are not cloned".

Do you know what points do the Java specification mean?


Why do conclude that the keys or values are copied when you clone the hashtable? When you call the put() methed on the cloned hashtable, it simply replaces the old reference with the new reference. You can't make the conclusion that the old reference was a copy of the original and not the same reference.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Actually, this is a good example of why a shallow copy is fine for most cases of cloning a hashtable. The operations on the hashtable are just with references -- and will not change the object itself. The only time that you need a deep copy, is when you manipulate both the hashtable and the objects in the hashtable itself. For objects likes strings, it is fine because these objects can't be changed.

Henry
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Henry,


Originally posted by Henry Wong:
Actually, this is a good example of why a shallow copy is fine for most cases of cloning a hashtable. The operations on the hashtable are just with references -- and will not change the object itself. The only time that you need a deep copy, is when you manipulate both the hashtable and the objects in the hashtable itself. For objects likes strings, it is fine because these objects can't be changed.

Henry


Your reply is very helpful! Do you mean shallow copy of clone related concepts means copy only the reference?

Could you please show me some sample source codes dealing with why shallow copy is not enough and deep copy is needed?


regards,
George
[ May 16, 2005: Message edited by: George Lin ]
Ragu Ram
Greenhorn

Joined: Mar 08, 2004
Posts: 14
Do you mean shallow copy of clone related concepts means copy only the reference?

Yes
Could you please show me some sample source codes dealing with why shallow copy is not enough and deep copy is needed?




Result is

:::Test1
:::Test2


This shallow copy applies to all Collections and arrays.
Note that you can clone an array also.

Going for shallow/deep copy is not a rule of thumb and your business scenario dictates which one you are to choose.

In the example given above deep copy is not possible as MyClass doesnt implement the Cloneable interface.

I am wondering whether all the keys and values are needed to be serializable if I want to use your method


You guessed it right all the key/value pairs need to be serializable. I am not sure if having them Externalizable helps.
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961

It is highly appreciated if you could provide some sample source codes about your method. :-)


Hi, George. Here it comes:



Notice how hashcodes are different, meaning different object from the original to the deserialized. Object of the list have to be serializable, of course.
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Edwin,


Originally posted by Edwin Dalorzo:


Notice how hashcodes are different, meaning different object from the original to the deserialized. Object of the list have to be serializable, of course.


Your reply and sample are very helpful! Your method is very novel!

I have an issue dealing with your sample. I think if the hash code values of two objects are different, then I think the two objects are different (not pointing to the same memory space). But I am not quite sure about this point. Am I correct? Do you have any online materials dealing with hash code computation, which can show that if two objects are different, then the hash values are different?


regards,
George
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Ragu,


Originally posted by Ragu Ram:


Result is


You guessed it right all the key/value pairs need to be serializable. I am not sure if having them Externalizable helps.


Your reply is very helpful! In your sample, when you are talking about shallow copy is not enough, do you mean the content of the "cloned" table "my2ndTable" could be affected by the original object reference "m"?

In the example given above deep copy is not possible as MyClass doesnt implement the Cloneable interface.


I do not agree with this point. I think we can copy MyClass objects manually, by creating new objects and set the values for each of its member variable field, even though it is not an efficient and intelligent method. I am wondering why you mentioned the "Cloneable" interface at this point?


You guessed it right all the key/value pairs need to be serializable. I am not sure if having them Externalizable helps.


I am always using Interface "Serializable", and I am wondering what is the use of Interface "Externalizable".


regards,
George
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Originally posted by Mr. Linn


I have an issue dealing with your sample. I think if the hash code values of two objects are different, then I think the two objects are different (not pointing to the same memory space). But I am not quite sure about this point. Am I correct? Do you have any online materials dealing with hash code computation, which can show that if two objects are different, then the hash values are different?


Hi, George. First notice that I am using the System.identityHashCode() and not the hashCode method of the Objects stored in the list. That is because hashCode method of the objects stored in the list could have been overriden and idententityHashCode() guarantees it will return the same hashCode() as it would have been returned by the Object class if the hashCode method would have not been overriden (as it is in this case because the list contains String objects).

The contract for the Object.hashCode says (JSDK 1.4 Documentation on Object Class)


As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)



You can test two Object are equal also using the equality operators (==, !=)

that's to say



While
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Edwin, your reply is very great!!


Originally posted by Edwin Dalorzo:
Hi, George. First notice that I am using the System.identityHashCode() and not the hashCode method of the Objects stored in the list. That is because hashCode method of the objects stored in the list could have been overriden and idententityHashCode() guarantees it will return the same hashCode() as it would have been returned by the Object class if the hashCode method would have not been overriden (as it is in this case because the list contains String objects).


I have got all of your points except this one, the overriden issue. Could you please provide some sample cource codes to illustrate why identityHashCode is more convenient than hashCode method (I always use hashCode before)? What are your points when describing hashCode method by using String objects?


String a = new String("George");
String b = new String("George");System.out.println(a==b); //Should print false and identityHashCodes are different


I have tested that the output is true, which is not the same as we imagined. Do you know what is the reason?


regards,
George

[ May 18, 2005: Message edited by: George Lin ]
[ May 18, 2005: Message edited by: George Lin ]
Ragu Ram
Greenhorn

Joined: Mar 08, 2004
Posts: 14

Originally posted by George Lin
do you mean the content of the "cloned" table "my2ndTable" could be affected by the original object reference "m"?

Yes. The example demonstrated it right?

Originally posted by George Lin
I do not agree with this point.I think we can copy MyClass objects manually, by creating new objects and set the values for each of its member variable field, even though it is not an efficient and intelligent method. I am wondering why you mentioned the "Cloneable" interface at this point?

I agree with you that it is possible to copy objects by getting and setting stuff in a new object.
This is not cloning. but copying. For cloning an object that object needs to implement the clone interface.


Output is
:::Test1
:::Test1


I am wondering what is the use of Interface "Externalizable"

Externalizable is an alternative to Serializable and it provides some call back methods to write the contents to a stream.

I am not very strong on this Class. have a look at the api It will give you some light on this.


I have tested that the output is true, which is not the same as we imagined. Do you know what is the reason?


Check out the hashCode and equals contracts.
If object1.equals(object2) then object1.hashCode must be = object1.hashCode()

The reverse ned not be true.
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Hi, George.

Originally posted by George Lin


I have got all of your points except this one, the overriden issue. Could you please provide some sample cource codes to illustrate why identityHashCode is more convenient than hashCode method (I always use hashCode before)? What are your points when describing hashCode method by using String objects?



Goerge, I am not saying that identityHashCode is better than hashCode itself. What you have to understand is that some classes override hashCode. Why? Most of time because these classes have already overriden the equals method. If two classes are said to be equal they musth have the same hashCode value returned, the contrary is not necesarily true, that's to say: two objects with the same hashCode are not necesarily equal. Why so? Because to different classes could have overriden the hashCode method producing the same hashCode, but no representing equals objects.

This firs snippet shows two object of type Integer (which overrides hashCode to represent its integer value)




Now two object with same hashCOde but are not the same type, not even value



Now two objects that overrides hashCode, most probably it is because the object has an overriden equals method too. That means that two object my be equal and yet not being represting the same object in memory.



Now, the original equals method, the one that comes from object return true if two object represent the same memory reference, that is to say they are compared using the equality operator ==.

So, once you have overriden the equals method the only way you have to obatin the value of hashCode as it would have been originally returned by the Object.hashCode method is to call System.identityHashCode().

Different indentityHashCode would prove to objects are different, because that would prove that they are different memory references.

And finally, this code...



...does produce false. I have tested it, and I see false in my output monitor.
[ May 19, 2005: Message edited by: Edwin Dalorzo ]
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Ragu,


Originally posted by Ragu Ram:
[QB]


Your reply is very helpful! I think in your sample, when the statement "MyClass m1 = (MyClass) m.clone();" is invoked, then the String member variable "myStr" is copied (cloned). But I do not quite understand how this member variable is copied. You simply invoked "super.clone()", and how does this statement make "myStr" be copied?


regards,
George
George Lin
Ranch Hand

Joined: Jan 11, 2005
Posts: 125
Thanks Edwin,


Originally posted by Edwin Dalorzo:
So, once you have overriden the equals method the only way you have to obatin the value of hashCode as it would have been originally returned by the Object.hashCode method is to call System.identityHashCode().

Different indentityHashCode would prove to objects are different, because that would prove that they are different memory references.

[ May 19, 2005: Message edited by: Edwin Dalorzo ][/QB]


Your answer is great!

I think your purpose of using System.identityHashCode() is to identify whether two objects are pointing to the same memory. Am I correct?

I am wondering why you do not use "==". From your reply, I think "==" is the same as comparing return values from "System.identityHashCode()". Could you please help?


regards,
George
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Question about clone a Hashtable