HashMap源码 jdk1.8
慢慢来
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {}
tableSizeFor(int)
根据给定的容量大小,返回指定的int类型的数,这个数是2的次幂。看源码:
/** * Returns a power of two size for the given target capacity. */ static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }
姿势:
- 无符号右移 === 除以2的n次幂
-
public void run(){ int n = 16; System.out.println(n>>>1);//除以2的1次方 System.out.println(n<<1);//乘以2的1次方 System.out.println(n>>>2);//除以2的2次方 } /* 结果 */ 8 32 4
-
- |= 对两边的数进行或运算遇一则一
-
let a = 5; // 00000000000000000000000000000101 a |= 3; // 00000000000000000000000000000011 console.log(a); // 00000000000000000000000000000111
-
姿势总结:
源码中对给定的数进行除以2的1、2、4、8、16次幂的同时进行或等运算,这样就将给定数的二进制第一个1开始之后的所有位都补齐1。
栗子:
-
-
/* 32 的 二进制 100000 补齐1 之后是 111111 返回63 31 的 二进制 011111 补齐1 之后是 011111 返回31 */
-
给定数的对应2的次幂返回值。
transient Node<K,V>[] table;
姿势:
transient /* 实现Serializable接口,使用transient关键字的属性不会被序列化 该变量内容在序列化后无法获得访问。*/
属性
DEFAULT_INITIAL_CAPACITY 初始容量
/** * The default initial capacity - MUST be a power of two. * 初始化的容量16,一定是2的倍数 */ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
MAXIMUM_CAPACITY 最大容量
/** * The maximum capacity, used if a higher value is implicitly specified * by either of the constructors with arguments. * MUST be a power of two <= 1<<30. * 最大容量等于2的30次方 */ static final int MAXIMUM_CAPACITY = 1 << 30;
DEFAULT_LOAD_FACTOR 默认加载因子 默认
/** * The load factor used when none specified in constructor. * 默认加载因子是0.75 */ static final float DEFAULT_LOAD_FACTOR = 0.75f;
TREEIFY_THRESHOLD 转为红黑树的临界值 默认
/** * The bin count threshold for using a tree rather than list for a * bin. Bins are converted to trees when adding an element to a * bin with at least this many nodes. The value must be greater * than 2 and should be at least 8 to mesh with assumptions in * tree removal about conversion back to plain bins upon * shrinkage. * nodes长度大于8 当容量大于64所有长度大于8的bins都会会转为红黑树,小于8的还是单向链表 */ static final int TREEIFY_THRESHOLD = 8;
UNTREEIFY_THRESHOLD 从红黑树转化为链表的临界值 默认
/** * The bin count threshold for untreeifying a (split) bin during a * resize operation. Should be less than TREEIFY_THRESHOLD, and at * most 6 to mesh with shrinkage detection under removal. * nodes长度等于6 bin 时变为链表 */ static final int UNTREEIFY_THRESHOLD = 6;
姿势:
- 链表的时间复杂度为 N/2
- 红黑树的时间复杂度为 logN(以二为底)
- 8/2 = 4 ,log8 = 3 ,8之后链表的时间复杂度程线性增长,而红黑树时间复杂度增长越来越慢。想想它们的图形。。
- 这里nodes个数变为8转为红黑树,6又转会链表:这里面有时间和空间上的权衡。
- 为啥不一直使用红黑树or链表?
- 6转为链表应该是防止频繁转换。
/* Because TreeNodes are about twice the size of regular nodes, we * use them only when bins contain enough nodes to warrant use * (see TREEIFY_THRESHOLD). And when they become too small (due to * removal or resizing) they are converted back to plain bins. In * usages with well-distributed user hashCodes, tree bins are * rarely used. Ideally, under random hashCodes, the frequency of * nodes in bins follows a Poisson distribution * (http://en.wikipedia.org/wiki/Poisson_distribution) with a * parameter of about 0.5 on average for the default resizing * threshold of 0.75, although with a large variance because of * resizing granularity. Ignoring variance, the expected * occurrences of list size k are (exp(-0.5) * pow(0.5, k) / * factorial(k)). The first values are: * * 0: 0.60653066 * 1: 0.30326533 * 2: 0.07581633 * 3: 0.01263606 * 4: 0.00157952 * 5: 0.00015795 * 6: 0.00001316 * 7: 0.00000094 * 8: 0.00000006 * more: less than 1 in ten million */
MIN_TREEIFY_CAPACITY 支持转为红黑树,数组(table)的最小长度 默认
/** * The smallest table capacity for which bins may be treeified. * (Otherwise the table is resized if too many nodes in a bin.) * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts * between resizing and treeification thresholds. * 支持转为红黑树的容量的最小值为64,小于64不转为红黑树 */ static final int MIN_TREEIFY_CAPACITY = 64;
int threshold;重组的数组个数阈值
/** * The next size value at which to resize (capacity * load factor). * 阈值 扩容的阈值 加载因子乘以容量 * @serial */ // (The javadoc description is true upon serialization. // Additionally, if the table array has not been allocated, this // field holds the initial array capacity, or zero signifying // DEFAULT_INITIAL_CAPACITY.) int threshold;
final float loadFactor;加载因子
/** * The load factor for the hash table. * 数组的加载因子 * @serial */ final float loadFactor;
/* ---------------- Public operations -------------- */

浙公网安备 33010602011771号