全文使用JDK11
本篇目录
List接口的继承关系
ArrayList继承关系
ArrayList底层数据结构
LinkedList继承关系
LinkedList底层数据结构
Vector集合
可以看到有74个不同的类和接口实现了List
这个接口,如果每一个都要学习的话,会很乏力。
更好的方法是学习我们常用的,以后有更多的时间再去慢慢拓展。
List
接口的继承关系由它的继承关系可以看到List
接口继承至Collection
接口,所以Collection
中有的方法,List
也继承过来了。
ArrayList
ArrayList
继承关系毋庸置疑ArrayList
集合是我们最常使用的集合之一,是List
接口的一个实现类。
Cloneable
是一个标记接口,只有实现这个接口后,然后在类中重写clone
方法,然后通过类调用clone
方法才能克隆成功,如果不实现这个接口,则会抛出CloneNotSupportedException
(克隆不被支持)异常。
AbstractList
是一个抽象类,它也实现了List
接口。那为什么ArrayList
继承它,而不是直接去实现List
接口呢?这是因为List
的实现类太多了,为了减少这些类的重复代码,所以将它们写成一个抽象类。各位在开发过程中也可以用一下这个思想。
RandomAccess
也是一个标记接口,只有实现这个接口后,就能支持快速随机访问。往上追溯,可以在Collections
接口中的binarySearch()
方法中会判断当前的List
是否实现了RandomAccess
接口,然后再决定使用for循环
的还是使用迭代器
的形式遍历当前List
。
Serializable
也是一个标记接口,只有实现了这个接口后,这个类才能进行序列化。
ArrayList
底层数据结构transient Object[] elementData;
从它的源码中可以看到底层是Object[]
,所以它可以存储几乎所有类型的数据。transient
关键字的作用是在序列化这个对象时,这个属性不会被序列化。
如果对ArrayList
感兴趣可以查看我另一篇对ArrayList
的详解,这篇文章的重心在介绍List
集合。
ArrayList集合深度解析及其使用优化
LinkedList
LinkedList
继承关系Cloneable
和Serializable
上面介绍ArrayList
的时候说过了,这里就不提了。
AbstractSequentialList
抽象类继承至AbstractList
抽象类,而在上面有介绍后者,它俩的区别在前者只支持按次序访问,后者支持随机访问。这就是为什么LinkedList
集合没有实现RandomAccess
接口,因为它不支持随机访问。
Deque
接口定义了一个双端队列,它提供了一系列针对队列首尾元素的操作方法。而LinkedList
实现了该接口,意味着它可以做为一个双端队列来使用。
LinkedList
底层数据结构private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
LinkedList
本质上是一个双向链表,item
存储着本身的元素,next
指向下一个Node
,prev
指向上一个Node
。如下图:
Vector
可以从Vector
的继承关系中看出,它与ArrayList
应该比较相似。
Vector
和ArrayList
的底层数据结构、初始容量、扩容方式等都差不多。
不同的地方是Vector
相对来说是线程安全的,因为它的大多方法都使用synchronized
关键字,如果开发者对线程安全有更高的要求,推荐使用Vector
。
对于Vector
的详解,后面我会专门写一篇来介绍。