2.map
linkedHashMap在hashMap上减少一条双向链表,使hashMap构造放弃键值对插入程序,并实现了按程序拜访
treeMap 红黑树(自均衡的排序二叉树)
一 list
3.arraylist
arraylist线程不平安,底层数组,反对快速访问,尾部有空余空间
在尾减少删除工夫复杂度都是O(1),在指定地位减少删除工夫复杂度是O(n),因为要一个一个挪
vector
线程平安,底层数组
4.linkedlist
线程不平安
底层双向链表(1.6以前循环链表),双向链表是由两个单向链形成的,双向循环链表是由两个单向环形成的
不反对快速访问
在头尾减少删除工夫复杂度是O(1),在指定地位减少删除工夫复杂度是O(n),因为要一个一个找到地位
每个元素要存前驱和后继元素的地位
5.RandomAccess 接口
标识此类是否有疾速定位拜访的能力,arraylist有,linkedlist没有
二 set
7.hashSet
hashSet 线程不平安,能够存null,基于hashmap实现
linkedHashSet
linkedHashSet 能够按增加程序遍历,基于linkedHashMap实现
TreeSet
treeSet能够按增加程序遍历,能够天然排序或定制排序,基于红黑树
三 map
8 hashTable
线程平安,因为外部办法根本都通过synchronized润饰
根本淘汰,且kv都不能为null否则会npe
初始大小11,扩容为2n+1,如果给出初始,会用你给的
jdk1.8前 数组+链表 拉链法解决抵触 jdk1.8后 链表长度大于阈值(默认为8)时将链表转化为红黑树缩小搜寻工夫(转成红黑树前会判断,如果数组长度小于64会先扩容)
② Hashtable(同一把锁) :应用 synchronized 来保障线程平安,效率十分低下。当一个线程拜访同步办法时,其余线程也拜访同步办法,可能会进入阻塞或轮询状态,如应用 put 增加元素,另一个线程不能应用 put 增加元素,也不能应用 get,竞争会越来越强烈效率越低。
hashMap
非线程平安,通过 (n - 1) & hash 判断以后元素寄存的地位,初始大小16,扩容为2的幂次(求地位的时候速度快),如果给出初始,会用比你给的略微大一点的2的幂次
多线程操作导致死循环问题次要起因在于并发下的 Rehash 会造成元素之间会造成一个循环链表。
treemap
相比于HashMap来说 TreeMap 次要多了对汇合中的元素依据键排序的能力以及对汇合内元素的搜寻的能力。
相等
hashCode()的默认行为是对堆上的对象产生独特值。即便两个对象的数据相等,因为是两个对象,他们的hash也不会相等。
根本对象 == 是比拟值,援用对象、包装对象是比拟地址
ConcurrentHashMap
JDK1.7 的 ConcurrentHashMap 底层采纳 分段的数组+链表 实现,JDK1.8 采纳的数据结构跟 HashMap1.8 的构造一样,数组+链表/红黑二叉树。
实现线程平安的形式(重要):
在 JDK1.7 的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了宰割分段(Segment),每一把锁只锁容器其中一部分数据,多线程拜访容器里不同数据段的数据,就不会存在锁竞争,进步并发访问率。 到了 JDK1.8 的时候曾经摒弃了 Segment 的概念,而是间接用 Node 数组+链表+红黑树的数据结构来实现,并发管制应用 synchronized 和 CAS 来操作。(JDK1.6 当前 对 synchronized 锁做了很多优化) 整个看起来就像是优化过且线程平安的 HashMap,尽管在 JDK1.8 中还能看到 Segment 的数据结构,然而曾经简化了属性,只是为了兼容旧版本;