List继承了Collection,是有序的列表.
实现类有ArrayList、LinkedList、Vector、Stack等
○ArrayList是基于数组实现的,是一个数组队列。可以动态的增加容量!
○LinkedList是基于链表实现的,是一个双向循环列表。可以被当做堆栈使用!
○Vector是基于数组实现的,是一个矢量队列,是线程安全的!
○Stack是基于数组实现的,是栈,它继承与Vector,特性是FILO(先进后出)!
使用场景
-
当集合中对插入元素数据的速度要求不高,但是要求快速访问元素数据,则使用ArrayList。
-
当集合中对访问元素数据速度不做要求不高,但是对插入和删除元素数据速度要求高的情况,则使用LinkedList。
3.当集合中有多线程对集合元素进行操作时候,则使用Vector!但是现在BVector现在一般不再使用,如需在多线程下使用,可以用CopyOnWriteArrayList,在java.util.concurrent包下。
4.当集合中有需求是希望后保存的数据先读取出来,则使用Stack。
性能测试
package com.company;
import java.util.*;
/**
* @program JavaLearn3Day
* @description:
* @author: Destiny
* @create: 2018/12/21 14:24
*/
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("\r");
System.out.println("....开始测试读取元素..........");
// 随机读取元素测试
readAccessData(arrayList,"ArrayList") ;
readAccessData(linkedList,"LinkedList") ;
readAccessData(vector,"Vector") ;
readAccessData(stack,"Stack") ;
System.out.println("\r");
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元素, 使用的时间是 649 ms
LinkedList : 插入 100000元素, 使用的时间是 16 ms
Vector : 插入 100000元素, 使用的时间是 710 ms
Stack : 插入 100000元素, 使用的时间是 508 ms
....开始测试读取元素..........
ArrayList : 随机读取 100000元素, 使用的时间是 3 ms
LinkedList : 随机读取 100000元素, 使用的时间是 5217 ms
Vector : 随机读取 100000元素, 使用的时间是 3 ms
Stack : 随机读取 100000元素, 使用的时间是 3 ms
....开始测试删除元素..........
ArrayList : 删除 100000元素, 使用的时间是 475 ms
LinkedList : 删除 100000元素, 使用的时间是 3 ms
Vector : 删除 100000元素, 使用的时间是 517 ms
Stack : 删除 100000元素, 使用的时间是 515 ms
从运行的结果来看,ArrayList读取速度快于LinkedList,而插入和删除速度又慢于LinkedList。
原因
(1)ArrayList随机读取的时候采用的是get(index),根据指定位置读取元素,而LinkedList则采用size/2 ,二分法去加速一次读取元素。
(2)ArrayList插入时候要判断容量,删除之后的所有元素都要向数组的前端移动。 而LinkedList直接插入,不用判断容量,删除的时候很轻松,只需要更新被删除元素附近的链接。(链表将每个对象存放在独立的节点中,每个节点还存放着序列中下一个节点的引用)
网友评论