容器
一:arrayList (数组)
private static final int DEFAULT_CAPACITY = 10;//默认容量
transient Object[] elementData;// 最底层的数组
private int size;//数组大小
arrayList 查找速度快
add 方法
① 确定是否扩容
② 添加进去
get方法
remove方法
结合arrayList图
二:linkList(链表)
linkList 查找速度慢
折半查找
三:HashMap (数组 + 链表 + 红黑树)
基础 Hash计算
Int hashCode值是自己
String hashCode 计算
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;// 当链表的值小于6则会从红黑树转回链表
static final int MIN_TREEIFY_CAPACITY = 64;
// 存储Node数组。
transient Node<K, V>[] table;
transient Set<Map.Entry<K, V>> entrySet;//用于缓存
/**
* The number of key-value mappings contained in this map.
*/
transient int size;
transient int modCount;
int threshold;
/**
* 加载因子
* The load factor for the hash table.
*/
final float loadFactor;
1、构造方法
开始看构造方法。
1.1 HashMap
构造一个空的 HashMap,默认初始容量(16)和默认负载因子(0.75)。
1.2 HashMap(int initialCapacity)
构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
1.3 HashMap(int initialCapacity, float loadFactor)
构造一个空的 HashMap具有指定的初始容量和负载因子。我们来分析一下。
最后调用了tableSizeFor,来看一下方法实现:
2、put方法
1.1
1.2我们可以看到put调用的是putVal来进行数据插入,但是要注意到key在这里执行了一下hash方法,来看一下Hash方法是如何实现的。
/**
* 按位异或运算(^):两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。
*
* 扰动函数————(h = key.hashCode()) ^ (h >>> 16) 表示:
* 将key的哈希code一分为二。其中:
* 【高半区16位】数据不变。
* 【低半区16位】数据与高半区16位数据进行异或操作,以此来加大低位的随机性。
* 注意:如果key的哈希code小于等于16位,那么是没有任何影响的。只有大于16位,才会触发扰动函数的执行效果。
* */
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
1.3 putVal 方法 关键代码
1)table >64 && 链表数量大于8时,转为红黑树。
1.4 resize方法(扩容机制)
/** 第一步:根据情况,调整新表的容量newCap和阈值newThr*/
/** 第二步:根据newCap和newThr,构建新数组 */
/** 初始化新表*/