一,线程安全性

Vector、Stack:线程安全

ArrayList、LinkedList:非线程安全

二,实现方式

LinkedList:双向链表

ArrayList,Vector,Stack:数组

三,容量扩展方面

由于ArrayList和Vector(Stack继承自Vector,只在Vector的基础上添加了几个Stack相关的方法,故之后不再对Stack做特别的说明)使用数组实现,当数组长度不够时,其内部会创建一个更大的数组,然后将原数组中的数据拷贝至新数组中

//ArrayList
public boolean add(E e) {
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
} public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
//如果这次扩展不能满足要求,那就直接用minCapacity
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

如需扩展,则每次至少扩展至(原长度*3)/2 + 1

//Vector
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
} private void ensureCapacityHelper(int minCapacity) {
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object[] oldData = elementData;
int newCapacity = (capacityIncrement > 0) ?
(oldCapacity + capacityIncrement) : (oldCapacity * 2);
//如果这次扩展不能满足要求,那就直接用minCapacity
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

如果在创建Vector时不指定capacityIncrement(自动扩展长度)的值,如需扩展,则每次至少扩展至原长度的2倍

四,效率方面

这里仅仅比较ArrayList和LinkedList之间的效率差异

1,查询

ArrayList直接通过下标进行定位

//ArrayList
public E get(int index) {
RangeCheck(index);//检查下标是否超过数组长度
return (E) elementData[index];
}

LinkedList则需要进行遍历,平均遍历次数应为n/4

//LinkedList
public E get(int index) {
return entry(index).element;
} private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Entry<E> e = header;
//size >>1 相当于size/2
//由于LinkedList由双向链表实现,故从离得较近的一端开始遍历更快
if (index < (size >> 1)) {
for (int i = 0; i <= index; i++)
e = e.next;
} else {
for (int i = size; i > index; i--)
e = e.previous;
}
return e;
}

对于指定位置查询,由于可以通过下标直接进行定位,ArrayList的速度远快于LinkedList

但是如果都为首尾位置的查询,情况会大为不同,因为LinkedList也是可以直接定位到首尾位置的

//LinkedList
public E getFirst() {
if (size==0)
throw new NoSuchElementException();
return header.next.element;
} public E getLast() {
if (size==0)
throw new NoSuchElementException();
return header.previous.element;
}

此时ArrayList和LinkedList的效率相同

2,插入

对于ArrayList,指定位置插入有可能首先需要对数组容量进行扩展,之后还有可能导致数组中的数据需要顺次移动(代码中通过数组拷贝实现,避免了数据一个一个的移动),极端情况下插入一个数据将进行两次数组拷贝

//ArrayList
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
ensureCapacity(size+1); //如必要,将对数组容量进行扩展
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}

如果不指定插入位置,则插入至数组末端,此时只需考虑可能的数组容量扩展对性能带来的影响

//ArrayList
public boolean add(E e) {
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}

由于LinkedList是由链表实现的,并没有指定位置插入的方法,即便如此,一切也显得如此美好

/LinkedList
public boolean add(E e) {
addBefore(e, header);
return true;
} private Entry<E> addBefore(E e, Entry<E> entry) {
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}

当然了,LinkedList可以直接将数据插入至首尾

//LinkedList
public void addFirst(E e) {
addBefore(e, header.next);
} public void addLast(E e) {
addBefore(e, header);
}

总体来说,LinkedList效率高于ArrayList,即使在末尾插入,ArrayList也需要考虑可能的容量扩展对性能带来的影响

3,修改

和查询属于同一种情况

4,删除

指定位置的删除和插入属于同一种情况

除了删除指定位置数据,ArrayList和LinkedList都包含一个clear()方法用来清除所有数据

//ArrayList
public void clear() {
modCount++; // Let gc do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
[java] view plain copy 在CODE上查看代码片派生到我的代码片
//LinkedList
public void clear() {
Entry<E> e = header.next;
while (e != header) {
Entry<E> next = e.next;
e.next = e.previous = null;
e.element = null;
e = next;
}
header.next = header.previous = header;
size = 0;
modCount++;
}

由于都需要进行遍历,故效率相同

ArrayList,LinkedList,Vector,Stack之间的区别的更多相关文章

  1. ArrayList LinkedList Vector

    ArrayList是基于数组实现的,没有容量的限制. 在删除元素的时候,并不会减少数组的容量大小,可以调用ArrayList的trimeToSize()来缩小数组的容量. ArrayList, Lin ...

  2. ArrayList, LinkedList, Vector - dudu:史上最详解

    ArrayList, LinkedList, Vector - dudu:史上最详解 我们来比较一下ArrayList, LinkedLIst和Vector它们之间的区别.BZ的JDK版本是1.7.0 ...

  3. ArrayList LinkedList Vector之间的区别

    List主要有ArrayList,LinkedList和vector三种实现.这三种都实现了List接口,使用方式也很相似,主要区别在于其实现方式的不同! 这三种数据结构中,ArrayList和Vec ...

  4. ArrayList,LinkedList,vector的区别

    1,Vector.ArrayList都是以类似数组的形式存储在内存中,LinkedList则以链表的形式进行存储. 2.List中的元素有序.允许有重复的元素,Set中的元素无序.不允许有重复元素. ...

  5. 集合类源码(二)Collection之List(ArrayList, LinkedList, Vector)

    ArrayList 功能 完全命名 public class ArrayList<E> extends AbstractList<E> implements List<E ...

  6. ArrayList,LinkedList,Vector集合的认识

    最近在温习Java集合部分,花了三天时间读完了ArrayList与LinkedList以及Vector部分的源码.之前都是停留在简单使用ArrayList的API,读完源码看完不少文章后总算是对原理方 ...

  7. java 中 ArrayList LinkedList Vector 三者的异同点

    1.ArrayList和Vector都是基于数组实现的,所以查询速度很快,增加和删除(非最后一个节点)速度慢: Vector是线程安全的,ArrayList不是. 2.LinkedList 是一个双向 ...

  8. java类集框架(ArrayList,LinkedList,Vector区别)

    主要分两个接口:collection和Map 主要分三类:集合(set).列表(List).映射(Map)1.集合:没有重复对象,没有特定排序方式2.列表:对象按索引位置排序,可以有重复对象3.映射: ...

  9. List的三个子类ArrayList,LinkedList,Vector区别

    一:List的三个子类的特点 ArrayList: 底层数据结构是数组,查询快,增删慢. 线程不安全,效率高.Vector: 底层数据结构是数组,查询快,增删慢. 线程安全,效率低.Vector相对A ...

随机推荐

  1. Rstdio中更换R版本

    1.打开Rstdio,选择Tool --> Global Options.

  2. 如何在github上fork一个项目来贡献代码以及同步原作者的修改

    [-] 如何贡献自己的力量 如何让自己的项目与原作者的项目保持同步 作为一个IT人,通过github进行学习是最快的成长手 段.我们可以浏览别人的优秀代码.但只看不动手还是成长得很慢,因此为别人贡献代 ...

  3. "Mac OS X"想要进行更改。键入管理员的名称和密码以允许执行此操作("Mac OS X"想使用系统钥匙串)

    不知什么时候开始,每次我在运行xcode在真机上,或者archive打包的时间,都会弹出输入用户名和密码的框,搞的烦死了: 解决方法: 打开钥匙串访问 双击那些密钥弹出框: 改变到允许所有应用程序访问 ...

  4. python代码风格指南:pep8 中文翻译

    摘要 本文给出主Python版本标准库的编码约定.CPython的C代码风格参见​PEP7.本文和​PEP 257 文档字符串标准改编自Guido最初的<Python Style Guide&g ...

  5. android sdk manager下载慢可以使用代理信息

    mirrors.neusoft.edu.cn  80

  6. 【转载】错误:ORA-28002: the password will expire within 7 days 解决方法

    免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:xwdreamer      原文地址: 错误:ORA-28002: the ...

  7. NYOJ-214 单调递增子序列(二) TLE 分类: NYOJ 2014-01-28 22:57 171人阅读 评论(0) 收藏

    #include<stdio.h> #include<stdlib.h> #define max(x,y) x>y?x:y #define MAXX 100005 int ...

  8. mongo二维数组操作

    有2个嵌套的数组: 如果我想查询comments里score大于5的记录: testProvider.find({"comments.score":{"$gt" ...

  9. php __FILE__,__CLASS__等魔术变量,及实例(转)

    今天看到一个魔术变量,是以前没见过的,__DIR__,我查了查,发现原来是php5.3新增的,顺便举几个例子,解释一下php的魔术变量 1,__FILE__ 文件的完整路径和文件名.如果用在被包含文件 ...

  10. YARN应用程序的开发步骤

    开发基于YARN的应用程序需要开发客户端程序和AppMaster程序: 我们基于程序自带的例子来实现提交application 到YARN的ResourceManger. Distributed Sh ...