以HashSet
Java 为例。把一根绳子放进去。将其序列化。你最终会得到一些字节 - bytesA
。
将bytesA
其反序列化为Object
- fromBytes
。
现在重新序列化fromBytes
,你就得到了另一个字节数组 - bytesB
。
奇怪的是,这两个字节数组不相等。一个字节不一样!为什么?有趣的是,这并不影响TreeSet
或HashMap
。但它确实会影响LinkedHashSet
.
Set<String> stringSet = new HashSet<>();
stringSet.add("aaaaaaaaaa");
//Serialize it
byte[] bytesA;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(stringSet);
out.flush();
bytesA = bos.toByteArray();
}
// Deserialize it
Object 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十六进制转储bytesA
00000000: aced 0005 7372 0011 6a61 7661 2e75 7469 ....sr..java.uti
00000010: 6c2e 4861 7368 5365 74ba 4485 9596 b8b7 l.HashSet.D.....
00000020: 3403 0000 7870 770c 0000 0010 3f40 0000 4...xpw.....?@..
00000030: 0000 0001 7400 0a61 6161 6161 6161 6161 ....t..aaaaaaaaa
00000040: 6178 ax
xxd十六进制转储bytesB
00000000: aced 0005 7372 0011 6a61 7661 2e75 7469 ....sr..java.uti
00000010: 6c2e 4861 7368 5365 74ba 4485 9596 b8b7 l.HashSet.D.....
00000020: 3403 0000 7870 770c 0000 0002 3f40 0000 4...xpw.....?@..
00000030: 0000 0001 7400 0a61 6161 6161 6161 6161 ....t..aaaaaaaaa
00000040: 6178 ax
第三行第六列是差异。
我使用的是 Java 11.0.3。
(解决)
根据 Alex R 的回应 - HashSet 的 writeObject 存储了backing 的capacity、loadFactor和,但它重新计算了容量:sizeHashMapreadObject
capacity = (int)Math.min((float)size * Math.min(1.0F / loadFactor, 4.0F), 1.07374182E9F);
除了健全性检查之外,它实际上忽略了capacity最初存储的值!
慕森王
相关分类