一 list
vector
线程安全,底层数组
linkedlist
线程不安全
底层双向链表(1.6以前循环链表),双向链表是由两个单向链构成的,双向循环链表是由两个单向环构成的
不支持快速访问
在头尾增加删除时间复杂度是O(1),在指定位置增加删除时间复杂度是O(n),因为要一个一个找到位置
每个元素要存前驱和后继元素的位置
RandomAccess 接口
标识此类是否有快速定位访问的能力,arraylist有,linkedlist没有
二 set
hashSet
hashSet 线程不安全,可以存null,基于hashmap实现
linkedHashSet
linkedHashSet 可以按添加顺序遍历,基于linkedHashMap实现
TreeSet
treeSet可以按添加顺序遍历,可以自然排序或定制排序,基于红黑树
三 map
linkedHashMap
在hashMap上增加一条双向链表,使hashMap结构保持键值对插入顺序,并实现了按顺序访问
hashTable
基本淘汰,且kv都不能为null否则会npe
初始大小11,扩容为2n+1,如果给出初始,会用你给的
jdk1.8前 数组+链表 拉链法解决冲突 jdk1.8后 链表长度大于阈值(默认为8)时将链表转化为红黑树减少搜索时间(转成红黑树前会判断,如果数组长度小于64会先扩容)
线程安全,因为内部方法基本都经过synchronized修饰,效率非常低下。当一个线程访问同步方法时,其他线程也访问同步方法,可能会进入阻塞或轮询状态,如使用 put 添加元素,另一个线程不能使用 put 添加元素,也不能使用 get,竞争会越来越激烈效率越低。
treemap
相比于HashMap来说 TreeMap 主要多了对集合中的元素根据键排序的能力以及对集合内元素的搜索的能力。
treeMap 红黑树(自平衡的排序二叉树)
相等
hashCode()的默认行为是对堆上的对象产生独特值。即使两个对象的数据相等,因为是两个对象,他们的hash也不会相等。
基本对象 == 是比较值,引用对象、包装对象是比较地址
ConcurrentHashMap
JDK1.7 的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟 HashMap1.8 的结构一样,数组+链表/红黑二叉树。
实现线程安全的方式(重要):
在 JDK1.7 的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。 到了 JDK1.8 的时候已经摒弃了 Segment 的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS(compare and swap) 来操作。(JDK1.6 以后 对 synchronized 锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在 JDK1.8 中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。