以HashSetJava 為例。把一根繩子放進去。將其序列化。你最終會得到一些字節 - bytesA。將bytesA其反序列化為Object- fromBytes。現在重新序列化fromBytes,你就得到了另一個字節數組 - bytesB。奇怪的是,這兩個字節數組不相等。一個字節不一樣!為什么?有趣的是,這并不影響TreeSet或HashMap。但它確實會影響LinkedHashSet.Set<String> stringSet = new HashSet<>();stringSet.add("aaaaaaaaaa");//Serialize itbyte[] bytesA;try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(stringSet); out.flush(); bytesA = bos.toByteArray();}// Deserialize itObject fromBytes;try (ByteArrayInputStream is = new ByteArrayInputStream(bytesA)) { try(ObjectInputStream ois = new ObjectInputStream(is)) { fromBytes = ois.readObject(); }}//Serialize it.byte[] bytesB;try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(fromBytes); out.flush(); bytesB = bos.toByteArray();}assert Arrays.equals(bytesA, bytesB); //array contents differ at index [43], expected: <16> but was: <2>如果這些有幫助: xxd十六進制轉儲bytesA00000000: aced 0005 7372 0011 6a61 7661 2e75 7469 ....sr..java.uti00000010: 6c2e 4861 7368 5365 74ba 4485 9596 b8b7 l.HashSet.D.....00000020: 3403 0000 7870 770c 0000 0010 3f40 0000 [email protected]: 0000 0001 7400 0a61 6161 6161 6161 6161 ....t..aaaaaaaaa00000040: 6178 axxxd十六進制轉儲bytesB00000000: aced 0005 7372 0011 6a61 7661 2e75 7469 ....sr..java.uti00000010: 6c2e 4861 7368 5365 74ba 4485 9596 b8b7 l.HashSet.D.....00000020: 3403 0000 7870 770c 0000 0002 3f40 0000 [email protected]: 0000 0001 7400 0a61 6161 6161 6161 6161 ....t..aaaaaaaaa00000040: 6178 ax第三行第六列是差異。我使用的是 Java 11.0.3。(解決)根據 Alex R 的回應 - HashSet 的 writeObject 存儲了backing 的capacity、loadFactor和,但它重新計算了容量:sizeHashMapreadObjectcapacity = (int)Math.min((float)size * Math.min(1.0F / loadFactor, 4.0F), 1.07374182E9F);除了健全性檢查之外,它實際上忽略了capacity最初存儲的值!
1 回答

慕森王
TA貢獻1777條經驗 獲得超3個贊
HashSet
如果使用構造函數創建 a,它會創建HashMap
默認大小為 16 的 a。
如果您反序列化它,并且您的集合包含的條目較少,則大小可能會初始化為小于 16。這就是本例中發生的情況。
看一下readObject
的實現,HashSet
看看大小是如何計算的。
打印兩個字節數組會提示您這確實發生了:
[..., 16, ...] [..., 2,...]
添加回答
舉報
0/150
提交
取消