/**
* 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 {
int buckets = capacity();
// Write out the threshold, loadfactor, and any hidden stuff
s.defaultWriteObject();
s.writeInt(buckets);
s.writeInt(size);
internalWriteEntries(s);
} /**
* Reconstitute the {@code HashMap} instance from a stream (i.e.,
* deserialize it).
*/
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
// Read in the threshold (ignored), loadfactor, and any hidden stuff
s.defaultReadObject();
reinitialize();
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new InvalidObjectException("Illegal load factor: " +
loadFactor);
s.readInt(); // Read and ignore number of buckets
int mappings = s.readInt(); // Read number of mappings (size)
if (mappings < 0)
throw new InvalidObjectException("Illegal mappings count: " +
mappings);
else if (mappings > 0) { // (if zero, use defaults)
// Size the table using given load factor only if within
// range of 0.25...4.0
float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
float fc = (float)mappings / lf + 1.0f;
int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
DEFAULT_INITIAL_CAPACITY :
(fc >= MAXIMUM_CAPACITY) ?
MAXIMUM_CAPACITY :
tableSizeFor((int)fc));
float ft = (float)cap * lf;
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
(int)ft : Integer.MAX_VALUE);
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
table = tab; // Read the keys and values, and put the mappings in the HashMap
for (int i = 0; i < mappings; i++) {
@SuppressWarnings("unchecked")
K key = (K) s.readObject();
@SuppressWarnings("unchecked")
V value = (V) s.readObject();
putVal(hash(key), key, value, false, false);
}
}
}

HashMap实现了Serizeble接口,说明能够被序列化 ,但是发现HashMap的成员变量  transient Node<K,V>[] table;transient Set<Map.Entry<K,V>> entrySet;transient int size;transient int modCount;。。。

都被transient修饰了,代表在序列化的时候忽略这些字段。

后面才发现HashMap实现了writeObject和readObject这两个方法那么序列化时就会调用该类的实现,如果没有的话就会使用defaultWriteObject()和defaultReadObject(),而HashMap就是自己实现了writeObject和readObject方法,自己对table做了处理。

必须注意地是,writeObject()与readObject()都是private方法,那么它们是如何被调用的呢?毫无疑问,是使用反射。详情可见ObjectOutputStream中的writeSerialData方法,以及ObjectInputStream中的readSerialData方法。

HashMap如何实现序列化的更多相关文章

  1. 【集合框架】JDK1.8源码分析之HashMap(一)

    一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也 ...

  2. JDK1.8源码分析之HashMap(一) (转)

    一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也 ...

  3. java 8 Hashmap深入解析 —— put get 方法源码

    每个java程序员都知道,HashMap是java中最重要的集合类之一,也是找工作面试中非常常见的考点,因为HashMap的实现本身确实蕴含了很多精妙的代码设计. 对于普通的程序员,可能仅仅能说出Ha ...

  4. java集合系列——Map之HashMap介绍(八)

    1.HashMap的简介 (JDK1.7.0_79版本) HashMap是基于哈希表的Map实现的的,一个Key对应一个Value,允许使用null键和null值,不保证映射的顺序,特别是它不保证该顺 ...

  5. 【集合框架】JDK1.8源码分析之HashMap(一) 转载

    [集合框架]JDK1.8源码分析之HashMap(一)   一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化 ...

  6. 走进Java Map家族 (1) - HashMap实现原理分析

    在Java世界里,有一个古老而神秘的家族——Map.从底层架构到上层应用,他们活跃于世界的每一个角落.但是,每次出现时,他们都戴着一张冷硬的面具(接口),深深隐藏着自己的内心.所有人都认识他们,却并非 ...

  7. JDK1.8 HashMap源码分析

      一.HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时 ...

  8. 集合之HashMap(含JDK1.8源码分析)

    一.前言 之前的List,讲了ArrayList.LinkedList,反映的是两种思想: (1)ArrayList以数组形式实现,顺序插入.查找快,插入.删除较慢 (2)LinkedList以链表形 ...

  9. Java集合类源码解析:HashMap (基于JDK1.8)

    目录 前言 HashMap的数据结构 深入源码 两个参数 成员变量 四个构造方法 插入数据的方法:put() 哈希函数:hash() 动态扩容:resize() 节点树化.红黑树的拆分 节点树化 红黑 ...

随机推荐

  1. Vue2.X 通过 ajax 获取 API 数据(非 axios)

    不多废话,笔记如下 1. javascript: let vm = new Vue({ el: '#card-text', data: { info: '' }, beforeCreate: func ...

  2. 不基于比较的排序算法:Counting-sort和Radix-sort

  3. Nginx如何配置反向代理

    server { listen 80; server_name 代理域名; location / { proxy_pass 应用域名:应用端口; proxy_set_header Host $host ...

  4. 修改MySQL表中自增编号

    alter table 表名 AUTO_INCREMENT = 值 例:

  5. Efficient Estimation of Word Representations in Vector Space (2013)论文要点

    论文链接:https://arxiv.org/pdf/1301.3781.pdf 参考: A Neural Probabilistic Language Model (2003)论文要点  https ...

  6. lsusb查看usb设备

    root@ubuntu:/home/lyd/work/code/cyusb# lsusb Bus 001 Device 009: ID 04b4:00f1 Cypress Semiconductor ...

  7. 多线程-生产者消费者(BlockingQueue实现)

    三.采用BlockingQueue实现 BlockingQueue也是java.util.concurrent下的主要用来控制线程同步的工具. BlockingQueue有四个具体的实现类,根据不同需 ...

  8. nginx反向代理原理及配置详解

    nginx概述nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外n ...

  9. Gym - 101170B British Menu (强连通缩点+dp)

    题意:求一个有向图上的最长路(每个强连通分量的点不超过5个) 首先对强连通分量缩点,暴力预处理出len[k][i][j]表示第k个强连通分量里的第i个点和第j个点之间的最长路径,设状态(k,i,f)表 ...

  10. BZOJ1787 [Ahoi2008]Meet 紧急集合[结论题]

    location. 求到树上三点距离和最短的点及此距离. 这个不还是分类讨论题么,分两类大情况,如下图. 于是乎发现三个点对的lca中较深的那个lca是答案点.距离就是两两点对距离加起来除以2即可.这 ...