HashMap реализует интерфейс Serializable; поэтому он может быть сериализован. Я посмотрел на реализацию HashMap, а таблица Entry [] отмечена как переходная. Поскольку таблица Entry [] - это та, которая хранит все содержимое Карты, и если она не может быть сериализована, как построена Карта во время де-сериализации
Сериализуемость HashMap
Ответ 1
Если вы посмотрите на источник, вы увидите, что он не полагается на механизм сериализации по умолчанию, но вручную выписывает все записи (в качестве переменного потока ключи и значения):
/**
* Save the state of the <tt>HashMap</tt> instance to a stream (i.e.,
* serialize it)
*
* @serialData The <i>capacity</i> of the HashMap (the length of the
* bucket array) is emitted (int), followed by the
* <i>size</i> (an int, the number of key-value
* mappings), followed by the key (Object) and value (Object)
* for each key-value mapping. The key-value mappings are
* emitted in no particular order.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
Iterator<Map.Entry<K,V>> i =
(size > 0) ? entrySet0().iterator() : null;
// Write out the threshold, loadfactor, and any hidden stuff
s.defaultWriteObject();
// Write out number of buckets
s.writeInt(table.length);
// Write out size (number of Mappings)
s.writeInt(size);
// Write out keys and values (alternating)
if (i != null) {
while (i.hasNext()) {
Map.Entry<K,V> e = i.next();
s.writeObject(e.getKey());
s.writeObject(e.getValue());
}
}
}
Это более компактно, чем массив, который может содержать много пустых записей и цепочек ссылок и накладных расходов для оболочек карт $.
Обратите внимание, что он все еще вызывает defaultWriteObject
для полей "easy". Чтобы это сработало, он должен отметить все остальное как transient
.
Ответ 2
HashMap
заботится о своей собственной сериализации с помощью методов writeObject
и readObject
.
Ответ 3
HashMaps не сериализуют свои объекты Entry во время сериализации. Взгляните на его метод writeObject
.
javadocs объясняют:
Емкость HashMap (длина массива ковша) равна испускаемый (int), за которым следует размер (int, число ключевых значений сопоставления), за которым следует ключ (объект) и значение (объект) для каждого отображение ключевого значения. Сопоставления ключевых значений испускаются не порядок.
Если вы посмотрите на метод readObject
, вы увидите, как таблица записей перестраивается с использованием размеров, ключей и значений.