**一.总结概述 **

  1. List继承了Collection,是有序的列表。
  2. 实现类有ArrayList、LinkedList、Vector、Stack等
  • ArrayList是基于数组实现的,是一个数组队列。可以动态的增加容量!
  • LinkedList是基于链表实现的,是一个双向循环列表。可以被当做堆栈使用!
  • Vector是基于数组实现的,是一个矢量队列,是线程安全的!
  • Stack是基于数组实现的,是栈,它继承与Vector,特性是FILO(先进后出)!

二.使用场景

在实际的应用中如果使用到队列,栈,链表,首先可以想到使用List。不同的场景下面使用不同的工具,效率才能更高!

  1. 当集合中对插入元素数据的速度要求不高,但是要求快速访问元素数据,则使用ArrayList!
  2. 当集合中对访问元素数据速度不做要求不高,但是对插入和删除元素数据速度要求高的情况,则使用LinkedList!

    3.当集合中有多线程对集合元素进行操作时候,则使用Vector!但是现在BVector现在一般不再使用,如需在多线程下使用,可以用CopyOnWriteArrayList,在java.util.concurrent包下。

    4.当集合中有需求是希望后保存的数据先读取出来,则使用Stack!

三.性能测试

/*
* @author 阿飞
* 性能测试,通过插入、随机读取和删除对ArrayList、LinkedList、Vector和Stack进行测试!
* 结论:看LinkedList
* 插入10万个元素,LinkedList所花时间最短:17 ms。
* 删除10万个元素,LinkedList所花时间最短: 9 ms。
* 遍历10万个元素,LinkedList所花时间最长:10255 ms;而ArrayList、Stack和Vector则相差不多,都只用了几秒。
* (1) 对于需要快速插入,删除元素,应该使用LinkedList。
* (2) 对于需要快速随机访问元素,应该使用ArrayList。
*
*/
public class ListTest { private static final int COUNT = 100000; //十万 private static ArrayList<Object> arrayList = new ArrayList<Object>();
private static LinkedList<Object> linkedList = new LinkedList<Object>();
private static Vector<Object> vector = new Vector<Object>();
private static Stack<Object> stack = new Stack<Object>(); public static void main(String[] args) {
System.out.println("....开始测试插入元素.........."); // 插入元素测试
insertData(arrayList,"ArrayList") ;
insertData(linkedList,"LinkedList") ;
insertData(vector,"Vector") ;
insertData(stack,"Stack") ; System.out.println("....开始测试读取元素.........."); // 随机读取元素测试
readAccessData(arrayList,"ArrayList") ;
readAccessData(linkedList,"LinkedList") ;
readAccessData(vector,"Vector") ;
readAccessData(stack,"Stack") ; System.out.println("....开始测试删除元素.........."); // 随机读取元素测试
deleteData(arrayList,"ArrayList") ;
deleteData(linkedList,"LinkedList") ;
deleteData(vector,"Vector") ;
deleteData(stack,"Stack") ; } /**
* 指定的List 的子类中插入元素,并统计插入的时间
* @param list List 的子类
* @param name 子类的名称
*/
private static void insertData(List<Object> list,String name) {
long startTime = System.currentTimeMillis(); // 向list的位置0插入COUNT个数
for (int i=0; i<COUNT; i++){
list.add(0, i);
} long endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println(name + " : 插入 "+COUNT+"元素, 使用的时间是 " + interval+" ms");
} /**
* 指定的List 的子类中删除元素,并统计删除的时间
* @param list List 的子类
* @param name 子类的名称
*/
private static void deleteData(List<Object> list,String name) {
long startTime = System.currentTimeMillis(); // 删除list第一个位置元素
for (int i=0; i<COUNT; i++)
list.remove(0); long endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println(name + " : 删除 "+COUNT+"元素, 使用的时间是 " + interval+" ms");
} /**
* 指定的List 的子类中读取元素,并统计读取的时间
* @param list List 的子类
* @param name 子类的名称
*/
private static void readAccessData(List<Object> list,String name) {
long startTime = System.currentTimeMillis(); // 读取list元素
for (int i = 0; i < COUNT; i++)
list.get(i); long endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println(name + " : 随机读取 "+COUNT+"元素, 使用的时间是 " + interval+" ms");
}
}

运行结果:

....开始测试插入元素..........
ArrayList : 插入 100000元素, 使用的时间是 970 ms
LinkedList : 插入 100000元素, 使用的时间是 17 ms
Vector : 插入 100000元素, 使用的时间是 968 ms
Stack : 插入 100000元素, 使用的时间是 888 ms
....开始测试读取元素..........
ArrayList : 随机读取 100000元素, 使用的时间是 6 ms
LinkedList : 随机读取 100000元素, 使用的时间是 10255 ms
Vector : 随机读取 100000元素, 使用的时间是 8 ms
Stack : 随机读取 100000元素, 使用的时间是 4 ms
....开始测试删除元素..........
ArrayList : 删除 100000元素, 使用的时间是 1460 ms
LinkedList : 删除 100000元素, 使用的时间是 9 ms
Vector : 删除 100000元素, 使用的时间是 1472 ms
Stack : 删除 100000元素, 使用的时间是 894 ms

4.分析ArrayList和LinkedList运行结果

从运行的结果可以看出,ArrayList和LinkedLis适用各自的场景中!

为什么ArrayList读取速度快于LinkedList,而插入和删除速度又慢于LinkedList?

前面章节分析了这两个类的源码!

(1)ArrayList随机读取的时候采用的是get(index),根据指定位置读取元素,而LinkedList则采用size/2 ,二分法去加速一次读取元素!

源代码如下:

ArrayList:

 public E get(int index) {
rangeCheck(index); return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];//直接通过数组的下标来读取元素
}

LinkedList:

Node<E> node(int index) {
// assert isElementIndex(index); if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}

(2)ArrayList插入时候要判断容量,删除时候要将数组移位,有一个复制操作!而LinkedList直接插入,不用判断容量,删除的时候也是直接删除跳转指针节点,没有复制的操作!

源代码如下:

ArrayList:

public boolean add(E e) {
ensureCapacityInternal(size + 1); // 判断是否要增容
elementData[size++] = e;
return true;
}

LinkedList:

public boolean add(E e) {
linkLast(e);
return true;
} void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}

欢迎访问我的csdn博客,我们一同成长!

"不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!"

博客首页:http://blog.csdn.net/u010648555

java集合系列——List集合总结(六)的更多相关文章

  1. Java多线程系列--“JUC集合”02之 CopyOnWriteArrayList

    概要 本章是"JUC系列"的CopyOnWriteArrayList篇.接下来,会先对CopyOnWriteArrayList进行基本介绍,然后再说明它的原理,接着通过代码去分析, ...

  2. Java多线程系列--“JUC集合”03之 CopyOnWriteArraySet

    概要 本章是JUC系列中的CopyOnWriteArraySet篇.接下来,会先对CopyOnWriteArraySet进行基本介绍,然后再说明它的原理,接着通过代码去分析,最后通过示例更进一步的了解 ...

  3. Java多线程系列--“JUC集合”04之 ConcurrentHashMap

    概要 本章是JUC系列的ConcurrentHashMap篇.内容包括:ConcurrentHashMap介绍ConcurrentHashMap原理和数据结构ConcurrentHashMap函数列表 ...

  4. Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

    概要 本章对Java.util.concurrent包中的ConcurrentSkipListMap类进行详细的介绍.内容包括:ConcurrentSkipListMap介绍ConcurrentSki ...

  5. Java多线程系列--“JUC集合”06之 ConcurrentSkipListSet

    概要 本章对Java.util.concurrent包中的ConcurrentSkipListSet类进行详细的介绍.内容包括:ConcurrentSkipListSet介绍ConcurrentSki ...

  6. Java多线程系列--“JUC集合”07之 ArrayBlockingQueue

    概要 本章对Java.util.concurrent包中的ArrayBlockingQueue类进行详细的介绍.内容包括:ArrayBlockingQueue介绍ArrayBlockingQueue原 ...

  7. Java多线程系列--“JUC集合”08之 LinkedBlockingQueue

    概要 本章介绍JUC包中的LinkedBlockingQueue.内容包括:LinkedBlockingQueue介绍LinkedBlockingQueue原理和数据结构LinkedBlockingQ ...

  8. Java多线程系列--“JUC集合”09之 LinkedBlockingDeque

    概要 本章介绍JUC包中的LinkedBlockingDeque.内容包括:LinkedBlockingDeque介绍LinkedBlockingDeque原理和数据结构LinkedBlockingD ...

  9. Java多线程系列--“JUC集合”10之 ConcurrentLinkedQueue

    概要 本章对Java.util.concurrent包中的ConcurrentHashMap类进行详细的介绍.内容包括:ConcurrentLinkedQueue介绍ConcurrentLinkedQ ...

  10. Java多线程系列--“JUC集合”01之 框架

    概要 之前,在"Java 集合系列目录(Category)"中,讲解了Java集合包中的各个类.接下来,将展开对JUC包中的集合进行学习.在学习之前,先温习一下"Java ...

随机推荐

  1. LeetCode Weekly Contest 47

    闲着无聊参加了这个比赛,我刚加入战场的时候时间已经过了三分多钟,这个时候已经有20多个大佬做出了4分题,我一脸懵逼地打开第一道题 665. Non-decreasing Array My Submis ...

  2. 部分iphone手机上的div的点击事件无效

    最近在做一个手机移动端的项目,Andrio手机和部分iphone手机上点击事件都是好的,只有在老的型号上的iphone手机上点击事件无效果. 后来在网上查了很多资料,发现有加样式cursor:poin ...

  3. MVC客户端验证

    引用JS 注意:删除Layout里面默认引用的JQUERY,否则可能引起JS冲突. <link href="~/Content/Site.css" rel="sty ...

  4. Centos 6系统修复grub

    author:JevonWei 版权声明:原创作品 错误界面如下时,应该是grub的stage数据有缺失,应该从新安装grub GRUB引导的stage1阶段损坏,系统启动会直接进入光盘引导界面,st ...

  5. 从源码分析java.lang.String.isEmpty()

    今天在写代码的时候用到了java.lang.String.isEmpty()的这个方法,之前也用过,今天突发奇想,就看了看源码,了解了解它的实现方法,总结出来,大家可以交流交流. 通常情况下,我们使用 ...

  6. 实现点击后创建div,若对div2秒无操作则将div隐藏,鼠标移上div让它不隐藏,移出div超过两秒则div隐藏

    $('.addLabel').on('click', function () { setTimeout(function(){ if(hoverflag==0){ $(".labelHide ...

  7. 正则语言引擎:一个简单LEX和YACC结合运用的实例

    本文先描述了LEX与YACC的书写方法.然后利用LEX与YACC编写了一个简单正则语言的引擎(暂时不支持闭包与或运算),生成的中间语言为C语言. 正则引擎应直接生成NFA或DFA模拟器的输入文件,但在 ...

  8. JavaScript中你所不知道的Object(二)--Function篇

    上一篇(JavaScript中你所不知道的Object(一))说到,Object对象有大量的内部属性,而其中多数和外部属性的操作有关.最后留了个悬念,就是Boolean.Date.Number.Str ...

  9. Java Object中的equals和hashCode

    Java的Object对象中有两个方法比较有意思,一个是equals(),一个是hashCode(),那么这两个的作用有些同学可能还不是很清楚,那么同学们现在就进一步了解一下吧. 下面咱们写一个简单的 ...

  10. Node.js之eventproxy详解

    安装 npm install eventproxy --save 调用 var EventProxy = require('eventproxy'); 异步协作 多类型异步协作 此处以页面渲染为场景, ...