有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java哈希映射可序列化性

HashMap实现了可序列化接口;所以它可以被序列化。我已经研究了HashMap的实现,条目[]表被标记为transient。由于条目[]表是存储映射的全部内容的表,如果无法序列化,那么在反序列化期间映射是如何构造的


共 (3) 个答案

  1. # 1 楼答案

    哈希映射在序列化期间不会序列化其条目对象。看看它的writeObject方法

    javadocs解释道:

    The capacity of the HashMap (the length of the bucket array) is emitted (int), followed by the size (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.

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

  2. # 2 楼答案

    如果查看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包装器的开销

    注意,它仍然为“easy”字段调用defaultWriteObject。为了让它工作,它必须将所有其他内容标记为transient

  3. # 3 楼答案

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