Deserialized Set different hash code than before serializing

Viewed 139

Using Apache Commons 3 to serialize a Set (doesn't seem to matter as using Object streams also leads to same problem):

HashSet<String> hashSet = new HashSet<>();
byte[] serialized = SerializationUtils.serialize(hashSet);

HashSet<String> deserialized = SerializationUtils.deserialize(serialized);

// OK, works    
assertEquals(hashSet, deserialized);

byte[] serializedAfterDeserializing = SerializationUtils.serialize(deserialized);

// Nope, different!
assertArrayEquals(serialized, serializedAfterDeserializing);

Anyone has any idea why at the byte level they are not the same?

Doesn't matter if the HashSet has any element or not, even being empty it's not the same.

Using ArrayList the last assert works.

2 Answers

Sure. You certainly shouldn't expect serialization of HashSet to be deterministic. The hash table may have a different order for all sorts of reasons, e.g. that the table is differently sized when created from scratch versus when deserialized when you know exactly how many elements the table will have.

If you inspect both sets (hashSet and deserialized) you will find out that backing map has different initial capacity. Before serialization it was 16 and after set was serialized and deserialized it was set to 1. Both sets are still equal but have different binary representation.

Related