一、继承关系图
- Collection集合主要分为两个类,第一类是实现了List接口的类,如LinkedList、ArrayList、Vector;
- 另一类就是实现了Set接口的类,如LinkedHashSet、HashSet、TreeSet。这些类都是继承了AbstractCollection集合的类
- 实现了List接口的类和实现了Set接口的类的不同点在于,前者集合中可以出现重复的元素,而后者集合之中不允许出现重复的元素
- 实现了了List接口的类和实现了Set接口的这些类除了Vector这个集合是线程安全的,其他集合都是线程非安全的
- 实现List接口的类都可以添加的元素都是有序的,而Set集合并不保证添加元素的有序性
二、 实现List接口中的类比较
比较元素 |
ArrayList |
LinkedList |
Vector |
数据结构 |
数组 |
链表 |
数组 |
插入元素 |
慢 |
快 |
慢 |
删除元素 |
慢 |
快 |
慢 |
随机访问 |
快 |
慢 |
快 |
线程安全 |
不安全 |
不安全 |
安全 |
初始容量 |
10 |
null |
10 |
扩容机制 |
1.5倍 |
无 |
|
- 从上面的总结我们可以看出,ArrayList和Vector底层采用的都是数组数据结构,而LinkedList采用的链表的数据结构
- 对于插入一个元素到指定的位置,由于ArrayList和Vector采用的是数组的形式,所以需要先将原先的元素进行复制,然后再插入。而LinkedList直接通过改变要插入的节点的指针即可。所以插入元素时,LinkedList比ArrayList和Vector的要快。
- 对于删除指定位置的元素和插入元素类似,ArrayList和Vector需要进行一次复制然后执行删除,所以没有LinkedList执行的速度快(其实这里是有一点问题的就是我们要删除一个LinkedList中的元素需要先将进行一次查找,然后进行删除,时间复杂度都是O(n))
- 对于随机访问,ArrayList和Vector采用数组结构可以根据数组索引进行定位,因此能够快速的访问,而LinkedList最坏的情况可能需要O(n)的时间。
- 对于Vector因为底层实现的方法都是采用了synchronized方法,所以是线程安全的,而ArrayList和LinkedList则是线程不安全的
- 对于ArrayList和Vector如果我们不指定初始容量,那么初始化的容量为10,LinkedList初始化为null.
- ArrayList 和Vector的需要扩容机制而LinkedList不需要,ArrayList在添加元素的时候,会判断需要是否需要扩容,如果需要则扩容为之前的1.5倍,而Vector则是扩容为之前的2倍。
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
int newCapacity = oldCapacity + (oldCapacity >> 1);
三、实现Set接口的类之间比较
比较 |
HashSet |
TreeSet |
EnumSet |
数据结构 |
HashMap |
TreeMap |
Enum数组 |
这里我们可以看到Set集合使用的数据结构是Map或者是Enum,因此详细的情况我们可以去看HashMap和TreeMap。