HashMap可序列化

时间:2011-08-18 07:05:16

标签: java serialization hashmap

HashMap实现了Serializable接口;所以它可以序列化。我查看了HashMap的实现,并将Entry []表标记为瞬态。由于Entry []表是存储Map的全部内容的表,如果无法序列​​化,那么在反序列化期间如何构建Map

3 个答案:

答案 0 :(得分:35)

如果查看the source,您会发现它不依赖于默认的序列化机制,而是手动写出所有条目(作为密钥和值的交替流):

/**
  * 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());
                }
            }
        }

这比数组更紧凑,数组可以包含许多空条目和链接链以及Map $ Entry包装器的开销。

请注意,它仍会为“简单”字段调用defaultWriteObject。为了使其起作用,必须将其他所有内容标记为transient

答案 1 :(得分:9)

HashMap通过使用writeObjectreadObject方法来处理自己的序列化。

答案 2 :(得分:4)

HashMaps在序列化期间不会序列化其Entry对象。看看它的writeObject方法。

javadocs解释:

  

HashMap的容量(桶阵列的长度)是   emit(int),后跟size(一个int,键值的数量   映射),后跟每个的键(Object)和值(Object)   键值映射。键值映射没有特别发出   顺序。

如果查看readObject方法,您将看到如何使用大小,键和值重建Entry表。