Java集合框架

2020-12-30  本文已影响0人  莫失莫忘X3
常用集合框架结构图

list

底层逻辑

使用数组存储数据(默认初始容量为10),每当向数组中添加元素时,都要去检查添加后元素的个数是否会超出当前数组的长度,如果超出,数组将会进行扩容(将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张)

特点
继承了数组的特性,可以通过下标索引直接查找到指定位置的元素,因此查找效率高O(1),但每次插入或删除元素,就要大量地移动元素,插入删除元素的效率低(增删效率低

ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍
Vector提供indexOf(obj, start)接口,ArrayList没有
Vector线程安全级别,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销

底层逻辑

使用双向链表实现,每个节点都有一个前驱(之前前面节点的指针)和一个后继(指向后面节点的指针)。LinkedList没有长度的概念,所以不存在容量不足的问题


双向链表

Set

底层逻辑

HashSet内部维护一个HashMap,实际存储的元素都存放在HashMap的key上面,而value中的值都是统一的一个固定对象private static final Object PRESENT = new Object();

Map

为什么采用这种结构来存储元素呢?

数组的特点:查询效率高,插入,删除效率低。
链表的特点:查询效率低,插入删除效率高。
在HashMap底层使用数组加(链表或红黑树)的结构完美的解决了数组和链表的问题,使得查询和插入,删除的效率都很高。

使用HashMap注意事项:
因为HashMap的内部扩容机制,每次扩容都是一笔大的开销。所以应尽量规避,例如实现定义HashMap的长度

JDK1.7版本的ConcurrentHashMap
采用Segment数组(分段锁)+HashEntry+红黑树的实现方式。Segment类似于HashMap的结构。

内部结构图

从上面的结构我们可以了解到,ConcurrentHashMap定位一个元素的过程需要进行两次Hash操作。
第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部。所以缺点便是查找数据需要进行两次hash

JDK1.8版本的ConcurrentHashMap
采用synchronized+CAS+HashEntry+红黑树的实现方式。
Java8 ConcurrentHashMap结构基本上和Java8的HashMap一样,区别在于采用CAS+Synchronized保证线程安全

CAS是一种乐观锁,包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存地址里面的值和A的值是一样的,那么就将内存里面的值更新成B

上一篇 下一篇

猜你喜欢

热点阅读