容器

一: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,构建新数组 */
/** 初始化新表*/

 

posted @ 2021-02-15 10:04  majingyun  阅读(51)  评论(0编辑  收藏  举报