Reputation: 376
I have a problem in Java hashtable serialization that seems illogical to me but i am not able to find out the error in the logic i am using. Here is what i am doing,
Hashtable sspsrpData = new Hashtable();
for(int i=0;i<Constants.secondayStructures.length;i++) {
SecondaryStructures ss = (SecondaryStructures)(data.get(Constants.secondayStructures[i]));
sspsrpData.put(Constants.secondayStructures[i], new SecStrucPSRP(ss.getSecStruct(),ss.getLengthCounts()));
}
FileOutputStream fos = null;
ObjectOutputStream out = null;
fos = new FileOutputStream(Constants.sspsrpData);
out = new ObjectOutputStream(fos);
out.writeObject(sspsrpData);
This piece of code should put 3 key-value pairs in the hashtable and also should serialize the thus formed hashtable. Now when i am trying to retrive them back in another program by this piece of code:
FileInputStream fis = null;
ObjectInputStream in = null;
fis = new FileInputStream(Constants.sspsrpData);
in = new ObjectInputStream(fis);
ssPsrp = (Hashtable)in.readObject();
The resulting hashtable has only 2 key-value pairs. Though the count in the hashtable says 3 i can only see 2 key value pairs in the hashtable. I do not understand whats going wrong!!
Can somebody point out where am i going wrong?
Thanks and Good day, Santhosh
Upvotes: 0
Views: 4209
Reputation: 659
Its a very important point in serialization topic. Hashtables storekey/value pairs in buckets, which is where an entry resides. The bucket location itself is made from the hashCode()
of the key. So, now, if the key is an object whose hashCode() function is not overridden (ie; its using Object.hashCode()
), then the generation of this hashcode value can be different from JVM to JVM or even from one program run to another. Almost certainly, when its deserialized, its not the same object, but rather a new reference of that instance, which can result in a different hashCode()
then at the time it was being serialized, thus resulting in either stream corruption OR simply object not found. You can do either this or provide a primitive datatype for the key. So, an Integer can be a key and you can use Hashtable.put(2, myValueObj)
; → since java autoboxes integer primitives.
Upvotes: 0
Reputation: 21
HashMap uses "open hashing". That means, if you insert two different items whose hashCode methods generate the same unique number (this sometimes occurs) then the hash table solves this collision by simply inserting both entries into the same place as a linked list. Take a look into one entry within the hash table in debug mode: There's also an attribute with the name "next". This is a pointer to one further entry which is located at the same position within the hash table. In other words: The HashMap implementation manages "linked lists" at every position in the table. If one or more entries get stored at the same location (if their hashCode method calculates the same value) then the concerning hash table position stores all these entries in a linked list.
The problem with serialization of hash tables is that the hash table stores the items internally at different locations. The concerning items do have different table positions before the serialization. After the deserialization you cannot find these items again because they are stored at differnt positions, now. I don't know whether this was the intention of Sun/Oracle. Is it a bug? I've got the same problem. I'm looking for any solution.
Upvotes: 2
Reputation: 1471
Maybe Constants.secondayStructures[0] .equals( Constants.secondayStructures[1] )
or Constants.secondayStructures[1] .equals( Constants.secondayStructures[2] )
Try a sspsrpData.size()
before serialize your object, to be sure it has the good size before serializing.
Upvotes: 1
Reputation: 376
Yes .. The strange thing all the 3 key-value pairs are identical (String - SecStrucPSRP object). All the objects are serializable. Only 2 of them are accessible while deserializing the hashtable ..
Upvotes: 0