zoukankan      html  css  js  c++  java
  • java集合系列——List集合总结(六)

    **一.总结概述 **

    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

  • 相关阅读:
    Asp.Net Web API 2第八课——Web API 2中的属性路由
    Asp.Net Web API 2第七课——Web API异常处理
    Asp.Net Web API 2第六课——Web API路由和动作选择
    Asp.Net Web API 2第五课——Web API路由
    开始学习python
    BMI 小程序 购物车
    深浅copy 文件操作
    字典 dict 集合set
    基本数据类型 (str,int,bool,tuple,)
    python 运算符
  • 原文地址:https://www.cnblogs.com/aflyun/p/6492791.html
Copyright © 2011-2022 走看看