1.HashMap添加元素
1.创建测试工程
2.第一次执行put方法
首先会根据key计算hashcode。然后执行putval方法。
3.putVal方法
先判断table数组是否为空,新创建的肯定为空,为空就进行扩容,扩容规则是,新创建的话初始容量为16,再次扩容的容量为16*0.75=12. 第二次扩容为当前的2倍
第一次添加,数组中还没有数据,肯定不会产生hash冲突,所以直接创建一个node节点,将数据添加进去。
添加之后,判断是否需要扩容,然后返回null,添加完成
4.第二次执行put方法
table容量够用,不需要resize了,通过hash计算出在数组的索引位置也不再为null了,因为第二次添加的key和第一次填的key相同,也就是产生了hash碰撞,会进入else判断。
- 第一个if: hash相同并且(key是同一个对象或者key不为null且原key和要添加的key equals比较返回true)则直接替换value的值
- else if: 判断是否是tree结构 ,是的话将节点添加到红黑树中,期间会判断key是否有相同的,有的话替换value
- else:说明是链表结构,此时会遍历链表,如果有key相同的,就替换value,没有的话,尾插法将node插入链表尾部。判断链表长度,如果长度大于8,table进行扩容,如果table长度大于64,转为树结构。
此时满足第一个,所以会进行value替换
5.流程图:
2.HashMap遍历
1.遍历key
可以获取key的set集合,然后遍历这个set集合
2.遍历key和value(entrySet)
可以获取到entrySet的set集合,然后遍历这个set集合获取想要的key和value
3.直接调用forEach方法
3.ArrayList添加元素
1.创建测试工程
2.执行第一次add方法
调用add方法,首先要判断当前集合的容量,传入初始size(值是0)+1
3.ensureCapacityInternal()方法
如果当前集合为初始状态,也就是集合中元素为空,会将集合大小设置为10.
然后再次确认容量,传入mincapacity(值是10),如果mincapacity-数据的长度大于0,就进入grow方法,此时10-0肯定大于0。
4.grow方法
先获取到原来数据的长度,此时为第一次添加,oldCapacity为0,下一步,newCapacity也为0,newCapacity-minCapacity<0满足,newCapacity的值为10,进入Arrays.copyOf()方法,传入当前的空数组和数组长度10
5.copyof()方法
调用System.arraycopy(ntive方法)方法,传入原数组和新建的大小为10的数组,将原数组的数据拷贝到copy这个数组,并返回copy这个数组
grow方法中,原数组就变成了容量为10的新数组
原数组中0位置的值变成了传入的e,size变为1,第一个元素添加完成。
6.执行第二次add方法
先确定容量
此时这个判断就不会通过了,数组不是初始化状态的了,会进入ensureExplicitCapacity方法
所需最小容量-当前数组 当前数组容量为10,所需最小容量为2,所以可以放下,不会进入grow。
此时集合中第二元素添加成功,返回true。数组1索引的位置就存入了当前的数据。size变为2。继续准备进行下一次添加。
4.ArrayList遍历
1.forEach方法
5.HashSet添加元素
遵循HashMap的添加规则