JDK源码学习之Vector、Stack与LinkedList
来源:互联网 发布:php fetch array 编辑:程序博客网 时间:2024/05/29 19:40
一、概述
Vector 是JDK1.0提供的集合类,Stack是Vector的子类,LinkedList是JKD1.2提供的,是双向链表。
二、源码分析
Vector的实现基本跟ArrayList一样,所以就不重复分析了,简单挑出几个方法进行分析
扩容方法:
private void ensureCapacityHelper(int minCapacity) {int oldCapacity = elementData.length;if (minCapacity > oldCapacity) { Object[] oldData = elementData; int newCapacity = (capacityIncrement > 0) ?(oldCapacity + capacityIncrement) : (oldCapacity * 2); if (newCapacity < minCapacity) {newCapacity = minCapacity; } elementData = Arrays.copyOf(elementData, newCapacity);} }
从该方法就能分析出来,Vector扩容的特点,Vector扩容取决于capacityIncrement变量的值,个人理解相当于步进长度,默认是0,Vector会进行两倍扩容,或者采取原容量+步进长度来扩容,ArrayList会增大0.5倍在加1(HashMap跟负载因子相关默认是0.75),其他方法基本跟ArrayList相同,不再赘述,但是需要注意的是Vector是线程安全的集合,内部方法基本都有同步锁。
下面再来看一下Stack“栈”,Stack是Vector的子类,通过一定的封装来达到LIFO后入先出来模拟栈的特性。常用的方法有如下三个:
public E push(E item) {addElement(item);return item; }
压栈,添加数据到栈里。
public synchronized E pop() {Eobj;intlen = size();obj = peek();removeElementAt(len - 1);return obj; }
弹栈,弹出最后插入的数据,其中的peek方法直接弹出最后数据,如果没有会抛出异常,所以遍历的时候要加上判断
empty()。另外Stack也是个线程安全类。
再来看一下LinkedList ,它也是List接口的一个实现类,支持clone,序列化,还是实现了Deque接口——双端接口,
所以LinkedList可以实现FIFO,或者实现栈的功能,它提供了丰富的方法让我们可以灵活使用来达到自己想要的效果。
先来看一下它的实现基础——属性
private transient Entry<E> header = new Entry<E>(null, null, null);//标示头元素
private transient int size = 0;//存储队列大小
其中Entry是一个静态类,内部属性有E element 存储当前节点的value,Entry<E> next 存储当前节点的下一个Entry的引用,Entry<E> previous 存储当前节点的前一个Entry的引用。所以整个LinkedList的内部数据结构我们就明白了,其实就是一个链表,我们可以通过header来从前向后,或者从后向前进行操作,从而实现双端操作。
默认生成的linkedList不会额外创建空间,header.next = header.previous = header;另外header是不存储数值的,只是作为一个标记节点,真正存储元素开始的位置是是header.next。整个LinkedList可以看做一个“环”。通过数据结构我们就能知道,LinkedList查找效率比较低——从头或者尾一步步找,但是删除效率很高——找到之后直接修改引用即可,不用像ArrayList还要复制数组,另外LinkedList也允许存入null
常用的方法有:
public E getFirst()//得到第一个的元素
public E getLast()//得到最后的元素
实现了List接口所以很多方法跟ArrayList一样,内部实现稍有不同
主要看一下删除方法
public E remove(int index) { return remove(entry(index)); } /** * Returns the indexed entry. */ private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; if (index < (size >> 1)) {//判断index离头还是尾近 for (int i = 0; i <= index; i++) e = e.next; } else { for (int i = size; i > index; i--) e = e.previous; } return e; }
private E remove(Entry<E> e) {if (e == header) throw new NoSuchElementException(); E result = e.element;e.previous.next = e.next;e.next.previous = e.previous; e.next = e.previous = null; e.element = null;size--;modCount++; return result; }
通过index查找速度比通过对象找快,内部有判断选择合适的方向开始查找,通过分析可以看出LinkedList的删除操作时间复杂度是o(n)(要先遍历查找)。
三、总结
Vector与Stack都是JDK1.0提供的线程安全类,由于同步效率比较低,没有同步需求的情况下不建议使用该集合。
LinkedList是非线程安全类,是双向链表,删除速度快,查找慢。
- JDK源码学习之Vector、Stack与LinkedList
- JDK源码学习之Arraylist与LinkedList
- JDK 1.8 Vector与Stack源码分析
- jdk源码学习笔记--LinkedList
- JDK源码阅读之LinkedList
- jdk集合源码之LinkedList
- jdk源码分析之LinkedList
- JDK之LinkedList源码解析
- jdk源码剖析之LinkedList
- JDK源码解析之LinkedList
- JDK源码走读之LinkedList
- JDK之Stack源码解析
- 【源码解析】JDK源码之LinkedList
- JDK源码解析之ArrayList与Vector与CopyOnWriteArrayList
- 给jdk写注释系列之jdk1.6容器(10)-Stack&Vector源码解析
- JDK之Vector源码解析
- JDK源码学习系列05----LinkedList
- java源码解读之LinkedList------jdk 1.7
- 对于UITableViewStyleGrouped类型的UITableView的背景色设置问题
- apache支持php 4.11 方法
- ASP.NET MVC3学习--视图和模型(3)
- CRC16校验
- web项目加解密
- JDK源码学习之Vector、Stack与LinkedList
- Cmake 模板和语法
- 为什么如此获取Java数组的长度
- 百度面试题:求绝对值最小的数
- Web服务器 Mongoose 的介绍与安装
- WP7 Isolated Storage 系列 - 4.读取和存储文本文件
- VS2008 快捷键汇总
- 搜集的各种推荐书籍(不晓得这辈子读得完不!)
- where T : class的含义