Difference between ArrayList and LinkedList

Generally, everyone knows the general difference between ArrayList and LinkedList: 
     1. ArrayList is a data structure based on dynamic arrays, and LinkedList is a data structure based on linked lists. 
     2. For random access get and set, ArrayList feels better than LinkedList, because LinkedList has to move the pointer. 
     3. For the add and remove operations, LinedList is more dominant, because ArrayList needs to move data. 

ArrayList and LinkedList are two collection classes used to store a series of object references (references). For example, we can use ArrayList to store a series of String or Integer. So what is the performance difference between ArrayList and LinkedList? When should I use ArrayList and when should I use LinkedList?


one. Time complexity 
The first key point is that the internal implementation of ArrayList is based on the underlying array of objects, so when it uses the get method to access any element in the list (random access), it is faster than LinkedList. The get method in LinkedList is to check sequentially from one end of the list to the other end. For LinkedList, there is no faster way to access a specific element in the list. 
Suppose we have a large list, and the elements in it have been sorted. This list may be of ArrayList type or LinkedList type. Now we do a binary search on this list. The comparison list is For the query speed of ArrayList and LinkedList, see the following program: 

package com.nanjing.dataStruc;

import java.util. *;

public class ListQueryTest{

    private static Integer[] array = new Integer[50000];
    private static List values;

    static {
        for (int i = 0; i < array.length; i++) {
            array[i] = i;
        }
        values = Arrays.asList(array);
    }

    public static long testQuery(List list) {
        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < array.length; i++) {
            int index = Collections.binarySearch(list, values.get(i));
            if (index != i)
                System.out.println("***错误***");
        }
        return System.currentTimeMillis() - beginTime;
    }

    public static void main(String[] args) {
        System.out.println("ArrayList query time:" + testQuery(new ArrayList(values)));
        System.out.println("LinkedList query time:" + testQuery(new LinkedList(values)));
    }
}

 

The output I get is:

ArrayList query time: 16

LinkedList query time: 23078

 
This result is not fixed, but basically the time of ArrayList is significantly smaller than that of LinkedList. So LinkedList should not be used in this case. The random access strategy used by the binary search method, while LinkedList does not support fast random access. The time spent doing random access to a LinkedList is proportional to the size of the list. Correspondingly, the time consumed by random access in ArrayList is fixed. 
Does this mean that ArrayList is always better than LinkedList? This is not necessarily the case, in some cases LinkedList performs better than ArrayList, and some algorithms are more efficient when implemented in LinkedList. For example, using the Collections.reverse method to reverse a list will perform better. 
Looking at an example like this, join we have a list to which a lot of insertions and deletions are going to be performed, in which case LinkedList is a better choice. Consider the following extreme example, where we repeatedly insert an element at the beginning of a list: 

package com.nanjing.dataStruc;

import java.util. *;

public class ListInsertTest {


    public static long testQuery(List list) {
        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < 50000; i++) {
            list.add(0,i);
        }
        return System.currentTimeMillis() - beginTime;
    }

    public static void main(String[] args) {
        System.out.println("ArrayList insertion time: " + testQuery(new ArrayList()));
        System.out.println("LinkedList insertion time:" + testQuery(new LinkedList()));
    }
}

 

At this point my output is:

ArrayList Insertion Time: 844

LinkedList Insertion Time: 16

 

This is the opposite of the result of the previous example, when an element is added to the beginning of the ArrayList, all existing elements are moved backward, which means the overhead of data movement and copying. Conversely, adding an element to the very beginning of a LinkedList simply assigns a record to that element, and then adjusts the two links. The overhead of adding an element at the beginning of a LinkedList is fixed, while the overhead of adding an element at the beginning of an ArrayList is proportional to the size of the ArrayList.


two. Space Complexity 
There is a private inner class in LinkedList, defined as follows:

    private static class Entry<E> {
	E element;
	Entry<E> next;
	Entry<E> previous;

	Entry(E element, Entry<E> next, Entry<E> previous) {
	    this.element = element;
	    this.next = next;
	    this.previous = previous;
	}
    }
 

每个Entry对象reference列表中的一个元素,同时还有在LinkedList中它的上一个元素和下一个元素。一个有1000个元素的LinkedList对象将有1000个链接在一起的Entry对象,每个对象都对应于列表中的一个元素。这样的话,在一个LinkedList结构中将有一个很大的空间开销,因为它要存储这1000个Entity对象的相关信息。 
ArrayList使用一个内置的数组来存储元素,这个数组的起始容量是10.当数组需要增长时,新的容量按如下公式获得:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%。这就意味着,如果你有一个包含大量元素的ArrayList对象,那么最终将有很大的空间会被浪费掉,这个浪费是由ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素,数组将不得不被重新进行分配以便能够增加新的元素。对数组进行重新分配,将会导致性能急剧下降。如果我们知道一个ArrayList将会有多少个元素,我们可以通过构造方法来指定容量。我们还可以通过trimToSize方法在ArrayList分配完毕之后去掉浪费掉的空间。


三.总结 
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下: 
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。


2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。


3.LinkedList不支持高效的随机元素访问。


4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间


可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326991605&siteId=291194637