什么是List
List接口中常用的三种linkedList,ArraylList,Vector。list接口定义了,我们开发需要的容器操作,是一个有序,值可重复的容器。
ArrayList
ArrayList本质上是一种数组,它不仅仅是数组,还是一个Resizable-array的数组
上面截图也描述的非常清楚,它是线程不安全的。
Vector则是线程安全的,线程安全所带来的弊端则是性能。目前Vector已经很少使用了。
构造方法
有3个构造方法,
第一个无参数构造方法,使用默认数组。
第二个自定义长度。
第三个预先数据插入数组中。
创建实例的时候不会定义capacity的大小,在第一次add数据的时候会进行相应的处理。(下面记录add和动态扩容)
动态扩容
进入add方法中,可以看到由两部分组成:
1. ensureCapacityInternal方法进行容量控制
2. ArrayList长度增加,并数组入值
第二步比较简单,进入第一步ensureCapacityInternal看详细,
这一步用于判断是否是无参数构造方法生成的实例,且第一次添加元素,这个是对 无参数的特殊处理。
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
进入ensureExplicitCapacity()方法
如果当前数组需要添加的数据超过数组的容量,就增加grow容量。
那么进入grow看看
新容量为之前容量的1.5倍,这里又加了两个判断,都是较为简单的,一个和当前最小值比较,和容量最大值比较,进行逻辑上的控制。
最后通过Array.copyOf产生扩容后的数组(更细的去调用底层c/c++)。
其他add方法,addAll方法,remove方法都类似,数组位置移动,扩容都很类似。写到这,感觉也不算特别高大上,比如这个Iterator的hasNext,就是判断是否cursor到size了。
fail-fast
这个是提供一个尽最大努力发现错误的一直措施,但不一定保证。提供一个modCount变量,本身不是线程安全的,每次对数组操作的时候自增,通过判断iterator的expectedModCount是否和ArrayList的modeCount一致,从而尽最大努力避免线程安全问题。
LinkedList
本质是一个双向链表,
有头节点,尾节点,和长度。
学过数据结构,对这些链表操作都是比较熟悉的。添加原始,修改对应的地址指向。
vector
和ArrayList相似,不过vector中大量用到Syncronized来保证线程安全。自身也是一个可变长度的数组。
结语
以上的内容也不是特别高大上,更多深入的还要到底层c/c++。路还长:-)