• ArrayList vs. LinkedList vs. Vector


    翻译自:ArrayList vs. LinkedList vs. Vector

    1.列表概览

    就像它的名字一样,List是一个元素的有序序列。当我们讨论列表时把它与Set(两两不等且无序的元素集合)进行比较是一个好主意。下面是容器的类层次图。从这个层次图中可以了解Java容器的一般概念。

    2.ArrayList vs. LinkedList vs. Vector

    从上图可知,它们都实现了List接口,而且用法很相似。它们主要的不同在于它们的实现导致的对不同的操作有不同的性能。
    ArrayList被实现为一个大小可变的数组。当有更多的元素添加到ArrayList时,它的大小会动态的增加。因为ArrayList本质上是一个数组,所以可以通过get()set()方法直接访问它的元素。
    LinkedList被实现为一个双向链表,在增加和删除元素的时候比ArrayList的性能要好,而对于get()set()方法性能就不及ArrayList了。
    Vector与ArrayList相似,但它是线程同步的。
    当程序是线程安全的时候,ArrayList是一个更好的选择。当添加更多的元素时,ArrayList和Vector会请求更多的空间,Vector每次会申请两倍于当前大小的空间,而ArrayList每次只会增加当前大小50%的空间。LinkedList还实现了Queue接口,使得它比ArrayList和Vector有更多的方法,比如offer()peek()poll()等。
    注意:ArrayList的初始容量非常小,所以以较大的初始容量构造ArrayList是一个很好的习惯,这样可以避免重新分配空间的花费。

    3.ArrayList示例

    ArrayList<Integer> al = new ArrayList<Integer>();
    al.add(3);
    al.add(2);      
    al.add(1);
    al.add(4);
    al.add(5);
    al.add(6);
    al.add(6);
    
    Iterator<Integer> iter1 = al.iterator();
    while(iter1.hasNext()){
        System.out.println(iter1.next());
    }
    

    4.LinkedList示例

    LinkedList<Integer> ll = new LinkedList<Integer>();
    ll.add(3);
    ll.add(2);      
    ll.add(1);
    ll.add(4);
    ll.add(5);
    ll.add(6);
    ll.add(6);
    
    Iterator<Integer> iter2 = ll.iterator();
    while(iter2.hasNext()){
        System.out.println(iter2.next());
    }
    

    就像上面示例中展示的一样,它们的用法很相似。真正的不同在于背后的实现和他们操作的复杂度。

    5.Vector

    Vector和ArrayList几乎完全一样,不同点是Vector是线程同步的。正因为这样,Vector比ArrayList有一个额外的开销。通常情况下,大多数Java程序员都会使用ArrayList,因为他们可以靠自己明确的实现同步。

    6.ArrayList和LinkedList的性能比较

    时间复杂度比较如下:
    这里写图片描述
    *表中add()指add(E e),remove()指remove(int index)
    *ArrayList在任意位置增加/删除操作的时间复杂度为O(n),但在列表尾的时间复杂度为O(1)。
    *LinkedList在任意位置增加/删除操作的时间复杂度为O(n),但在列表头/尾的时间复杂度为O(1)。
    可以用下面的代码测试它们的性能:

    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    LinkedList<Integer> linkedList = new LinkedList<Integer>();
    
    // ArrayList add
    long startTime = System.nanoTime();
    
    for (int i = 0; i < 100000; i++) {
        arrayList.add(i);
    }
    long endTime = System.nanoTime();
    long duration = endTime - startTime;
    System.out.println("ArrayList add:  " + duration);
    
    // LinkedList add
    startTime = System.nanoTime();
    
    for (int i = 0; i < 100000; i++) {
        linkedList.add(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println("LinkedList add: " + duration);
    
    // ArrayList get
    startTime = System.nanoTime();
    
    for (int i = 0; i < 10000; i++) {
        arrayList.get(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println("ArrayList get:  " + duration);
    
    // LinkedList get
    startTime = System.nanoTime();
    
    for (int i = 0; i < 10000; i++) {
        linkedList.get(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println("LinkedList get: " + duration);
    
    
    
    // ArrayList remove
    startTime = System.nanoTime();
    
    for (int i = 9999; i >=0; i--) {
        arrayList.remove(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println("ArrayList remove:  " + duration);
    
    
    
    // LinkedList remove
    startTime = System.nanoTime();
    
    for (int i = 9999; i >=0; i--) {
        linkedList.remove(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println("LinkedList remove: " + duration);
    

    输出如下:

    ArrayList add:  13265642
    LinkedList add: 9550057
    ArrayList get:  1543352
    LinkedList get: 85085551
    ArrayList remove:  199961301
    LinkedList remove: 85768810
    


    性能差别很明显,LinkedList在增加/删除元素方面更快,在访问元素时更慢。根据时间复杂度表和测试结果,我们可以知道什么时候用ArrayList或LinkedList。简单地说,在下面的情况时应该用LinkedList:
    没有大量的随机访问元素的操作;
    有大量增加/删除元素的操作。

    翻译自:ArrayList vs. LinkedList vs. Vector

  • 相关阅读:
    vbscript错误代码及对应解释大全(希望还没过时)
    对象存储服务MinIO安装部署分布式及Spring Boot项目实现文件上传下载
    一道算法题,求更好的解法
    浅谈SQLite——实现与应用
    Linux网络协议栈(二)——套接字缓存(socket buffer)
    服务器开发入门——理解异步I/O
    理解MySQL——复制(Replication)
    线性时间排序算法
    Linux网络协议栈(一)——Socket入门(2)
    理解MySQL——索引与优化
  • 原文地址:https://www.cnblogs.com/liushaobo/p/4423272.html
Copyright © 2020-2023  润新知