HashMap序列化 [英] HashMap Serializability

查看:140
本文介绍了HashMap序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

HashMap实现Serializable接口;所以它可以被序列化。我看了HashMap的实现,Entry []表被标记为transient。由于Entry []表是存储Map的全部内容的表,如果它不能被序列化,在反序列化过程中如何构造Map

解决方案

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

  / ** 
*保存< tt> HashMap< / tt>的状态实例转换为流(即
*序列化它)
*
* @serialData< i>容量< / i> (int),然后是
*< i>尺寸< / i>的HashMap(
*桶阵列的长度) (一个int,键值
*映射的数量),后面是每个键 - 值映射的键(Object)和值(Object)
*。键值映射是以不特定顺序排列的
*。
* /
private void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
Iterator< Map.Entry< K,V>> i =
(size> 0)? entrySet0()。iterator():null;

//写出阈值,loadfactor和任何隐藏的内容
s.defaultWriteObject();

//写出桶的数量
s.writeInt(table.length);

//写出大小(映射数量)
s.writeInt(size);

//写出键和值(交替)
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


HashMap implements the Serializable interface; so it can be serialized. I have looked at the implementation of HashMap and the Entry[] table is marked as transient. Since the Entry[] table is the one that stores the entire contents of the Map and if it cannot be serialized, how is the Map constructed back during de-serialization

解决方案

If you look at the source you will see that it does not rely on the default serialization mechanism, but manually writes out all the entries (as an alternating stream of keys and values):

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

This is more compact than the array, which can contain many empty entries and link chains and overhead for Map$Entry wrappers.

Note that it still invokes defaultWriteObject for the "easy" fields. In order for that to work, it has to mark everything else as transient.

这篇关于HashMap序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆