对于Java汇合的局部温习知识点整顿
ArrayList
- ArrayList实质上继承了AbstractList,而AbstractList则是继承了Collection汇合类,并且Arraylist是实现了List的接口
- ArrayList初始的容量,DEFAULT_CAPACITY = 10,即初始容量为10,但初始化对象的时候能够传入你自定义的容量最大容量为Interger.MaxValue-8
- ArrayList的默认元素存储,是一个Object[]数组
- ArrayList源码外面存在一个ensureCapacity的办法,用来确认数组的容量是否须要扩容,扩容的时候采纳的是Arrays.Copyof的办法,复制元素到一个新的数组
- 对于ArrayList的扩容机制,达到了定义容量(不传入容量的话,即为默认容量)的时候,会动静扩容1.5倍,也是采纳上述的复制办法
- ArrayList其实是存在手动缩容的办法的,在源码中有叫做 trimToSize()的办法,个别是手动调用的
- ArrayList中删除元素的Remove办法其实也是采纳arraycopy()的办法来进行元素的挪动,实质跟数组差不多
- ArrayList是线程不平安的,外面没有实现线程平安的保障,多线程在拜访的时候,实现的主动扩容也是造成线程不平安的一部分起因。相同,常见的Vector基本上是靠synchronized来实现线程平安的
HashMap
- HashMap实现了Map接口,初始容量为16,最大容量为1 << 30,默认加载因子为0.75,如果本人传入初始值K,则容量为大于K的2次方整数,例如:传入10的话,则容量为16
- HashMap的插入原理
在JDK1.8之前,HashMap应用数组+链表实现,即应用链表解决抵触,同一hash值的节点都存储在一个链表里。然而当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值顺次查找的效率较低。而JDK1.8中,HashMap采纳数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间,红黑树转链表的阈值是6
- hash函数是通过拿到key的hashcode,而后让hashcode的高16位和低16位进行异或操作,这样设计的起因是尽可能地减小hash碰撞,其二是位运算比拟高效
hashmap如果采纳头插法的话,在多线程的状况下会产生环,并且hashmap在多线程下也是不平安的,在JDK8之前的话,是先判断扩容再插入的,而JDK8之后则是先插入再判断是否须要扩容,扩容为扩容到原数组大小的2倍
- 扩容的时候1.7须要对原数组中的元素进行从新hash定位在新数组的地位,1.8采纳更简略的判断逻辑,地位不变或索引+旧容量大小
- 链表转红黑树,并不是达到8个Node节点的阈值就进行转换,而是要判断一下整个数据结构中的Node数量是否大于64,大于才会转,小于就会用扩容数组的形式代替红黑树的转换
扩大
Java中有HashTable、Collections.synchronizedMap、以及ConcurrentHashMap能够实现线程平安的Map。
- HashTable是间接在操作方法上加synchronized关键字,锁住整个数组,粒度比拟大;
- Collections.synchronizedMap是应用Collections汇合工具的外部类,通过传入Map封装出一个SynchronizedMap对象,外部定义了一个对象锁,办法内通过对象锁实现;
- ConcurrentHashMap应用分段锁,升高了锁粒度,让并发度大大提高。