ArrayList和LinkedList的区别

ArrayList使用一个内置的数组来存储元素,这个数组的起始容量是10,当数组需要增长时,新的容量按如下公式获得:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%。这就意味着,如果你有一个包含大量元素的ArrayList对象,那么最终将有很大的空间会被浪费掉,这个浪费的空间是由ArrayList的工作方式本身造成的。

ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的来说可以描述如下:

  1. 对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
  2. 在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList中间插入或删除一个元素的开销是固定的。
  3. LinkedList不支持高效的随机访问。
  4. ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间浪费主要体现在它的每一个元素都需要耗费相当的空间,LinkedList中有一个私有的内部类。

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

更多可参考他人文章学习:


作者:不玩藤球的猫
链接:https://www.jianshu.com/p/e591690afacb

下面搬砖以便回顾学习:

在java编程过程中,许多人惯使用并常用的的几个类型莫过于String,ArrayList以及HashMap了,以至于并没有关心过LinkedList及Hashtable等类型及它们的区别,致使写出的程序看似漂亮但是并不高效。
现在我来分享下我了解的ArrayList和LinkedList的区别。从数据结构上看,顾名思义,ArrayList是实现了基于动态数组的结构,而LinkedList则是基于实现链表的数据结构。而两种数据结构在程序上体现出来的优缺点在于增删和改查的速率,就此,我们分别作出说明。
数据的更新和查找
ArrayList的所有数据是在同一个地址上,而LinkedList的每个数据都拥有自己的地址.所以在对数据进行查找的时候,由于LinkedList的每个数据地址不一样,get数据的时候ArrayList的速度会优于LinkedList,而更新数据的时候,虽然都是通过循环循环到指定节点修改数据,但LinkedList的查询速度已经是慢的,而且对于LinkedList而言,更新数据时不像ArrayList只需要找到对应下标更新就好,LinkedList需要修改指针,速率不言而喻
数据的增加和删除
对于数据的增加元素,ArrayList是通过移动该元素之后的元素位置,其后元素位置全部+1,所以耗时较长,而LinkedList只需要将该元素前的后续指针指向该元素并将该元素的后续指针指向之后的元素即可。与增加相同,删除元素时ArrayList需要将被删除元素之后的元素位置-1,而LinkedList只需要将之后的元素前置指针指向前一元素,前一元素的指针指向后一元素即可。当然,事实上,若是单一元素的增删,尤其是在List末端增删一个元素,二者效率不相上下。

public static final int N = 50000; static void getTime(List list) { insertByPosition(list); readByPosition(list); updateByPosition(list); deleteByPosition(list); } // 向list的指定位置插入N个元素,并统计时间 private static void insertByPosition(List list) { long startTime = System.currentTimeMillis(); for (int i = 0; i < N; i++) list.add(0, i); long endTime = System.currentTimeMillis(); long interval = endTime - startTime; System.out.println(getListName(list) + "插入" + N + "条数据耗时:" + interval + " ms"); } //从list中读取元素,并统计时间 private static void readByPosition(List list) { long startTime = System.currentTimeMillis(); for (int i = 0; i < N; i++){ list.get(i); } long endTime = System.currentTimeMillis(); long interval = endTime - startTime; System.out.println(getListName(list) + "查询" + N + "条数据耗时:" + interval + "ms"); } // 从list的随机位置修改元素,并统计时间 private static void updateByPosition(List list) { long startTime = System.currentTimeMillis(); int M = 40000; for(int i=0;i<40000;i++){ int j = (int)(1+Math.random()*(40000-1+1)); list.set(j, "list"); } long endTime = System.currentTimeMillis(); long interval = endTime - startTime; System.out.println(getListName(list) + "随机修改" + M + "条数据耗时" + interval + " ms"); } // 从list的指定位置删除N个元素,并统计时间 private static void deleteByPosition(List list) { long startTime = System.currentTimeMillis(); // 删除list第一个位置元素 for (int i = 0; i < N; i++) list.remove(0); long endTime = System.currentTimeMillis(); long interval = endTime - startTime; System.out.println(getListName(list) + "删除" + N + "条数据耗时" + interval + " ms"); } //获取list类型名称 private static String getListName(List list) { if (list instanceof LinkedList) { return "LinkedList"; } else if (list instanceof ArrayList) { return "ArrayList"; } else { return "error"; } } public static void main(String[] args) { getTime(new ArrayList()); getTime(new LinkedList()); }