集合
HashMap的put方法的具体流程?
❒ HashMap源码分析-常见属性 // 数组默认的初始容量 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 // 数组最大长度 static final int MAXIMUM_CAPACITY = 1 << 30; // 负载因子 static final float DEFAULT_LOAD_FACTOR = 0.75f; // 树化阀值 static final int TREEIFY_THRESHOLD = 8; // 反树化阀值 static final int UNTREEIFY_THRESHOLD = 6; // 最小树化容量 static final int MIN_TREEIFY_CAPACITY = 64; transient HashMap.Node[] table transient int size; 扩容阈值 == 数组容量 * 加载因子 = 16 * 0.75 = 12 ✔ HashMap是懒惰加载,在创建对象时并没有初始化数组 ✔ 在无参的构造函数中,设置了默认的加载因子是0.75 ✔ 链表长度阈值:当单个桶中的链表长度达到8时(数组长度大于等于64),该链表会被转换为红黑树。 ✔ 最小树化容量:HashMap的总容量(桶数组大小)必须至少为64。如果容量小于64,即使链表长度达到8,也不会进行树化,而是会选择扩容。
❒ HashMap的put方法的具体流程? ✔ 判断键值对数组table是否为空或为null,否则执行resize()进行扩容(初始化)。 ✔ 根据键值key计算hash值得到数组索引。 ✔ 判断table[i]==null,条件成立,直接新建节点添加。 ✔ 如果table[i]==null,不成立。 1 判断table[i]的首个元素是否和key一样,如果相同直接覆盖value。 2 判断table[i]是否为treeNode,即table[i]是否是红黑树,如果是红黑树,则直接在树中插入键值对。 3 遍历tabe[i],链表的尾部插入数据,然后判断链表长度是否大于8(且数组长度大于64),大于8的话把链表转换为红黑树,在红黑树中执行插入操作,遍历过程中若发现key已经存在直接覆盖value。 ✔ 插入成功后,判断实际存在的键值对数量size是否超多了最大容量threshold(数组长度 * 0.75),如果超过,进行扩容。