【Stackoverflow好问题】LinkedList、ArrayList各自的使用场景,如何确认应该用哪一个呢?

问题

LinkedList、ArrayList各自的使用场景是什么,如何确认应该用哪一个呢?


精华回答

一言以蔽之,在大部分情况下,使用ArrayList会好一些。

一、耗时上各有优缺点。ArrayList稍有优势。

List只是一个接口,而LinkedList、ArrayList是List的不同实现。LinkedList的模型是双向链表,而ArrayList则是动态数组

首先对比下常用操作的算法复杂度

LinkedList

  • get(int
    index)
     : O(n)
  • add(E
    element)
     : O(1)
  • add(int
    index, E element)
     : O(n)
  • remove(int
    index)
     : O(n)
  • Iterator.remove() : O(1)
    <--- LinkedList<E>的主要优点
  • ListIterator.add(E
    element)
     is O(1) <---  LinkedList<E>的主要优点

ArrayList

  • get(int
    index)
     : O(1) <---  ArrayList<E>的主要优点
  • add(E
    element)
     : 基本是O(1) , 因为动态扩容的关系,最差时是 O(n)
  • add(int
    index, E element)
     : 基本是O( n - index) , 因为动态扩容的关系,最差时是 O(n)
  • remove(int
    index)
     : O(n - index) (例如,移除最后一个元素,是 O(1))
  • Iterator.remove() : O(n
    - index)
  • ListIterator.add(E
    element)
     : O(n - index)

LinkedList,因为本质是个链表,所以通过Iterator来插入和移除操作的耗时,都是个恒量,但如果要获取某个位置的元素,则要做指针遍历。因此,get操作的耗时会跟List长度有关

对于ArrayList来说,得益于快速随机访问的特性,获取任意位置元素的耗时,是常量的。但是,如果是add或者remove操作,要分两种情况,如果是在尾部做add,也就是执行add方法(没有index参数),此时不需要移动其他元素,耗时是O(1),但如果不是在尾部做add,也就是执行add(int
index, E element),这时候在插入新元素的同时,也要移动该位置后面的所有元素,以为新元素腾出位置,此时耗时是O(n-index)。另外,当List长度超过初始化容量时,会自动生成一个新的array(长度是之前的1.5倍),此时会将旧的array移动到新的array上,这种情况下的耗时是O(n)。

总之,get操作,ArrayList快一些。而add操作,两者差不多。(除非是你希望在List中间插入节点,且维护了一个Iterator指向指定位置,这时候linkedList能快一些,但是,我们更多时候是直接在尾部插入节点,这种特例的情况并不多)

二、空间占用上,ArrayList完胜

看下两者的内存占用图

这三个图,横轴是list长度,纵轴是内存占用值。两条蓝线是LinkedList,两条红线是ArrayList,可以看到,LinkedList的空间占用,要远超ArrayList。LinkedList的线更陡,随着List长度的扩大,所占用的空间要比同长度的ArrayList大得多。

注:从mid JDK6之后,默认启用了CompressedOops ,因此64位及32位下的结果没有差异,LinkedList
x64和LinkedList x32的线是一样的。

stackoverflow原址:

http://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist

专栏介绍:

非常喜欢stackoverflow,总能在上面找到疑难杂症的解决办法。偶然发现该网站有一个热度榜单。于是精选了热度较高的一些问题,阅读每个问题的答案,然后按照自己的理解梳理出来。因此,这些文章不是真正的翻译,而是按照自己的理解做了一些增删、润色,希望能把上面的讨论,更精简有效地分享给大家。

如需转载,请注明原文地址

http://blog.csdn.net/lizeyang

时间: 2025-01-05 17:12:21

【Stackoverflow好问题】LinkedList、ArrayList各自的使用场景,如何确认应该用哪一个呢?的相关文章

Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 Java 集合系列 05 Vector详细介绍(源码解析)和使用示例 Java 集合系列 06 Stack详细介绍(源码解析)和使用示例 Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和

(转)Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理.解决办法) Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例 Java 集合系列06之 Vector详细介绍(源码解析)和使用示例 Java 集合系列07之 Stack详细

[Java基础]ArrayList与LinkedList的区别和使用场景

首先,ArrayList和LinkedList都是Java中常见的容器类,都实现了list接口:但是因为各自实现list接口时,采用的数据结构不一样,导致他们在使用上存在差异. 下面就总结一下: 1. ArrayList是基于数组来实现的线性表,只不过它是可以动态扩展的.如果不指定ArrayList初始容量值,那么其采用默认的值10;若果向ArrayList中添加对象引用时,已经无法容纳时,会自动的扩展,扩展的系数为1.5: 2. ArrayList对于按照索引值查找是非常快速的,时间复杂度为O

【转】Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理.解决办法) Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例 Java 集合系列06之 Vector详细介绍(源码解析)和使用示例 Java 集合系列07之 Stack详细

Java _ JDK _ Arrays, LinkedList, ArrayList, Vector 及Stack

(最近在看JDK源码,只是拿着它的继承图在看,但很多东西不记录仍然印象不深,所以开始记录JDK阅读系列.) (一)Arrays Arrays比较特殊,直接继承自Arrays ->List(Interface) ->Collection(Interface). (Maybe因为Java中的数组本身就比较特殊?) 包含一些用来操作数组的一些方法,比如排序,搜索,复制,填充,toString方法等: 搜索使用二分搜索: 排序:使用DualPivotQuickSort中的排序算法,基本是改进版的快速排

LinkedList ArrayList测试2

下面测试他们的性能 如何 import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; public class ListTest { private static final int REPS =100; private a

LinkedList ArrayList测试

下面测试他们的性能 如何 import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; public class ListTest { private static final int REPS =100; private a

Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分

第1部分 List概括 先回顾一下List的框架图 (01) List 是一个接口,它继承于Collection的接口.它代表着有序的队列. (02) AbstractList 是一个抽象类,它继承于AbstractCollection.AbstractList实现List接口中除size().get(int location)之外的函数. (03) AbstractSequentialList 是一个抽象类,它继承于AbstractList.AbstractSequentialList 实现了

LinkedList/ArrayList

一.LinkedList双向链表:堆栈,队列,双端队列.public class LinkedList<E>    extends AbstractSequentialList<E>    implements List<E>, Deque<E>, Cloneable, java.io.Serializable