集合源码学习(四):Vector
来源:互联网 发布:知乎客户端 pc 编辑:程序博客网 时间:2024/06/05 13:27
Vector是什么?
Vector是一个集合,和在实现结构上和ArrayList很相似,包括增加,修改,删除等等操作,和ArrayList实现算法均一致。所以本篇博文不再像前一篇文章集合源码学习(三):ArrayList 般介绍具体实现类型方方面面。所以想继续了解Vector源码读者可以先看ArrayList这篇,再来读这篇就可以了。
而与ArrayList的最大不同点,就是Vector里面的方法都考虑了线程安全,在很多操作方法上都加了synchronized关键字
这篇文章主要分享一些不同与ArrayList特点的地方。
定义头
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
同样是可随机访问以及可克隆,继承子AbstractList等。
初始值以及扩容
关于扩容,在数值上和ArrayList并不相同,如果程序员没有指定初值Vector的大小,则默认为10,而在扩容方面,Vector则是用一个capacityIncrement来确定的,同时也要和程序员要求扩容大小来比较,具体看代码及注释:
/** * 初始值为设置值,增长值为0默认 */ public Vector(int initialCapacity) { this(initialCapacity, 0); } /** * 初始值为10,默认增长值为0. */ public Vector() { this(10); }
接下来是关于扩容方面:
依次调用ensureCapacity,ensureCapacityHelper,grow等方法,中间除了一些边界判断语句,基本都是层层嵌套,这里主要贴出grow方法代码:
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //由此可见,如果capacityIncrement>0,就会按照cpacityIncrement大小增加,否则就是2个oldCapacity。 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //如果min比调整后的大小还大,那就按照minCapacity来。 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
Collections里面的线程安全包装方法
Vector里面也有个subList方法来获得子串,但是与ArrayList的实现不同,因为它被设计为线程安全的,所以直接返回了一个线程安全的包装类,这里介绍一下基本原理。
第一步:
public synchronized List<E> subList(int fromIndex, int toIndex) { return Collections.synchronizedList(super.subList(fromIndex, toIndex), this); }
接下来进入Collections.synchronized查看:
static <T> List<T> synchronizedList(List<T> list, Object mutex) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list, mutex) : new SynchronizedList<>(list, mutex)); }
返回了一个SynchronizedRandomAccessList,那再去看这个类。
static class SynchronizedRandomAccessList<E> extends SynchronizedList<E> implements RandomAccess { ...SynchronizedRandomAccessList(List<E> list, Object mutex) { super(list, mutex); }
这个类完全指示对super的一个包装SynchronizedList,已看名字就知道是一个线程安全类:
... final List<E> list; SynchronizedList(List<E> list) { super(list); this.list = list; } SynchronizedList(List<E> list, Object mutex) { super(list, mutex); this.list = list; } public boolean equals(Object o) { if (this == o) return true; synchronized (mutex) {return list.equals(o);} } public int hashCode() { synchronized (mutex) {return list.hashCode();} } public E get(int index) { synchronized (mutex) {return list.get(index);} } public E set(int index, E element) { synchronized (mutex) {return list.set(index, element);} } public void add(int index, E element) { synchronized (mutex) {list.add(index, element);} } ...
可以发现里面有众多方法,并且都是Vector中操作名字相同的方法,指示都是对当前Vector加锁,再进行操作的线程安全方法。
而其中方法实现原理,都是基于适配器模式间接使用Vector来进行操作,这是典型java多态的应用,如果通过debug源码,可以很清楚的看清这一点。
以上就是Collections里面synchronizedList包装方法的原理,其他方法可以类比理解。
Vector里面的Spliterator-VectorSpliterator
或许会有一个疑问,Vector不是线程安全的么?为啥也有Spliterator?
对于Spliterator不懂的读者可以看我这篇文章:集合源码学习(二):Spliterator
Spliterator可是一个支持并行的迭代器啊。
不多说,先看看源码:
static final class VectorSpliterator<E> implements Spliterator<E> { private final Vector<E> list; private Object[] array; private int index; // current index, modified on advance/split private int fence; // -1 until used; then one past last index private int expectedModCount; // initialized when fence set ... 这些和ArrayListSpliterator没有特别之处,就不多说 ... public boolean tryAdvance(Consumer<? super E> action) { if (action == null) throw new NullPointerException(); int hi = getFence(), i = index; if (i < hi) { index = i + 1; @SuppressWarnings("unchecked") E e = (E)list.elementData[i]; action.accept(e); if (list.modCount != expectedModCount) throw new ConcurrentModificationException(); return true; } return false; } //forEachRemaining方法和tryAdvance原理类似
和ArrayListSpliterator一样,也会有expectedModCount来保证fast-fail机制,防止在通过迭代器遍历的时候,Vector结构突然被改变(add和remove)。而不同的是,VectorSpliterator还传入了一个Object[]数组,java里面数组也是引用类型,也就是把Vector中的elementData传进来了。这样在tryAdvance中,就可以获得Vector中元素了Vector中get方法是同步的),也就可以进行并行的tryAdvance和forEachRemaining操作了。
确实在Vector上收获蛮多喔^^
- 集合源码学习(四):Vector
- java1.8 过时集合源码学习:Vector
- java 中的集合(四) Vector源码分析
- 深入Java集合源码学习系列:Vector的实现原理
- 【Java集合源码剖析】Vector源码剖析
- 【Java集合源码剖析】Vector源码剖析
- 【Java集合源码剖析】Vector源码剖析
- 【Java集合源码剖析】Vector源码剖析
- 【Java集合源码剖析】Vector源码剖析
- 【Java集合源码剖析】Vector源码剖析
- 【Java集合源码剖析】Vector源码剖析
- 【Java集合源码剖析】Vector源码剖析
- 源码学习之Vector
- Vector源码学习
- Java集合源码学习(四)HashMap分析
- JAVA学习---集合系列---Vector
- List接口实现类-ArrayList、Vector、LinkedList集合深入学习以及源码解析
- 深入Java集合源码学习系列:比较ArrayList、Vector、LinkedList性能
- 小知识笔记
- [luogu 2419]牛大赛Cow Contest
- Excel图表—二项分布和正态分布的对应关系
- 利用python进入数据分析之usagov_bitly_data数据分析
- jquery清空多个input框
- 集合源码学习(四):Vector
- Hadoop介绍(四)Hbase
- 机器学习——特征工程之线性判别分析LDA
- 实验二:线性表实验-单链表的实现
- 未知文本自适应居中
- Java nio 详解
- 第5周项目2 建立链栈算法库
- python_lintcode_419罗马数字转整数_688The Number In Words
- poj2396 Budget