title: Serialization round trip of hash map does not preserve order
body: <p>I've noticed that with a recent version of Java (1.7.0_u51) serialization and deserialization of a hashmap no longer preservers the order of the elements in the hashmap. See the below example:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Test
  public void test() throws IOException, ClassNotFoundException {
      HashMap&lt;String, String&gt; map1 = new HashMap&lt;&gt;();
      map1.put("a1234567", "aaa");
      map1.put("b1234567", "bbb");
  
      System.out.println("Map1: " + map1.toString());
  
      byte[] serializedMap1 = objectToBytes(map1);
  
      System.out.println("Map1 Serialized: " + Arrays.toString(serializedMap1));
  
      Object map2 = bytesToObject(serializedMap1);
  
      System.out.println("Map2: " + map2.toString());
  
      byte[] serializedMap2 = objectToBytes((Serializable) map2);
  
      System.out.println("Map2 Serialized: " + Arrays.toString(serializedMap2));
  
      Object map3 = bytesToObject(serializedMap2);
  
      System.out.println("Map3: " + map3.toString());
  
      byte[] serializedMap3 = objectToBytes((Serializable) map3);
  
      System.out.println("Map3 Serialized: " + Arrays.toString(serializedMap3));
  
      Object map4 = bytesToObject(serializedMap3);
  
      System.out.println("Map4: " + map4.toString());
  
      byte[] serializedMap4 = objectToBytes((Serializable) map4);
  
      System.out.println("Map4 Serialized: " + Arrays.toString(serializedMap4));
  }
  
  private byte[] objectToBytes(Serializable obj) throws IOException {
      PoolByteArrayOutputStream bos = new PoolByteArrayOutputStream();
      try {
          ObjectOutputStream oos = new ObjectOutputStream(bos);
          oos.writeObject(obj);
          byte[] bytes = bos.toByteArray();
          oos.close();
          return bytes;
      } finally {
          bos.close();
      }
  }
  
  private Object bytesToObject(byte[] str) throws IOException, ClassNotFoundException {
      ByteArrayInputStream bis = new ByteArrayInputStream(str);
      ObjectInputStream ois = new ClassLoaderObjectInputStream(bis, null);
  
      Object obj = ois.readObject();
      ois.close();
      bis.close();
      return obj;
  }
  </code></pre>
  
  <p>The above test will output:</p>
  
  <pre><code>Map1: {a1234567=aaa, b1234567=bbb}
  Map1 Serialized: [-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 77, 97, 112, 5, 7, -38, -63, -61, 22, 96, -47, 3, 0, 2, 70, 0, 10, 108, 111, 97, 100, 70, 97, 99, 116, 111, 114, 73, 0, 9, 116, 104, 114, 101, 115, 104, 111, 108, 100, 120, 112, 63, 64, 0, 0, 0, 0, 0, 12, 119, 8, 0, 0, 0, 16, 0, 0, 0, 2, 116, 0, 8, 97, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 97, 97, 97, 116, 0, 8, 98, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 98, 98, 98, 120]
  Map2: {b1234567=bbb, a1234567=aaa}
  Map2 Serialized: [-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 77, 97, 112, 5, 7, -38, -63, -61, 22, 96, -47, 3, 0, 2, 70, 0, 10, 108, 111, 97, 100, 70, 97, 99, 116, 111, 114, 73, 0, 9, 116, 104, 114, 101, 115, 104, 111, 108, 100, 120, 112, 63, 64, 0, 0, 0, 0, 0, 1, 119, 8, 0, 0, 0, 2, 0, 0, 0, 2, 116, 0, 8, 98, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 98, 98, 98, 116, 0, 8, 97, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 97, 97, 97, 120]
  Map3: {a1234567=aaa, b1234567=bbb}
  Map3 Serialized: [-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 77, 97, 112, 5, 7, -38, -63, -61, 22, 96, -47, 3, 0, 2, 70, 0, 10, 108, 111, 97, 100, 70, 97, 99, 116, 111, 114, 73, 0, 9, 116, 104, 114, 101, 115, 104, 111, 108, 100, 120, 112, 63, 64, 0, 0, 0, 0, 0, 1, 119, 8, 0, 0, 0, 2, 0, 0, 0, 2, 116, 0, 8, 97, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 97, 97, 97, 116, 0, 8, 98, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 98, 98, 98, 120]
  Map4: {b1234567=bbb, a1234567=aaa}
  Map4 Serialized: [-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 77, 97, 112, 5, 7, -38, -63, -61, 22, 96, -47, 3, 0, 2, 70, 0, 10, 108, 111, 97, 100, 70, 97, 99, 116, 111, 114, 73, 0, 9, 116, 104, 114, 101, 115, 104, 111, 108, 100, 120, 112, 63, 64, 0, 0, 0, 0, 0, 1, 119, 8, 0, 0, 0, 2, 0, 0, 0, 2, 116, 0, 8, 98, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 98, 98, 98, 116, 0, 8, 97, 49, 50, 51, 52, 53, 54, 55, 116, 0, 3, 97, 97, 97, 120]
  </code></pre>
  
  <p>(Note this only appears to work with map key where the last 7 characters are equal)</p>
  
  <p>From the output above you can see the order continues to change after each serialization round trip.</p>
  
  <p>I understand that the internal order of a map is not guaranteed to be consistent and I am not relying on it but I would have assumed that after serialization round trips the serialized bytes would be identical when the map itself has not changed. </p>
  
  <p>What specifically changed in the JDK to cause this to happen? (Is it a bug in the JDK?)</p>
  
  <p>Is there a way to get consistently get the same serialized bytes for the same hashmap? (without using a different order preserving map)</p>