在实际开发中如何选择ArrayList


LinkedList和ArrayList是List接口的两种不同实现。LinkedList使用双向链表实现它。ArrayList使用动态重新调整数组的大小来实现它。

与标准链表和数组操作一样,各种方法将具有不同的算法运行时。

对于 LinkedList<E>
    1.get(int index)是O(n)(平均n / 4步)
    2.add(E element)是O(1)
    3.add(int index, E element)是O(n)(平均n / 4步),但O(1)时index = 0 <---LinkedList<E>的主要好处
    4.remove(int index)是O(n)(平均n / 4步)
    5.Iterator.remove()是O(1)。<---LinkedList<E>的主要好处
    6.ListIterator.add(E element)是O(1)<-- LinkedList<E> 这是主要的好处之一
    注意:许多操作平均需要n / 4步,最佳情况下需要恒定步数(例如索引= 0),最坏情况下需要n / 2步(列表中间)

对于 ArrayList<E>
    1.get(int index)是O(1) <---ArrayList<E>主要的好处
    2.add(E element)是O(1)摊销,但O(n)最坏情况,因为数组必须调整大小并复制
    3.add(int index, E element)是O(n)(平均n / 2步)
    4.remove(int index)是O(n)(平均n / 2步)
    5.Iterator.remove()是O(n)(平均n / 2步)
    6.ListIterator.add(E element)是O(n)(平均n / 2步)
    注意:许多操作平均需要n / 2步,最好的情况下是常数步(列表末尾),最坏情况下是n步(列表开头)

LinkedList<E>允许使用迭代器进行常量插入或删除,但只允许顺序访问元素。换句话说,您可以向前或向后遍历列表,但在列表中查找位置需要的时间与列表的大小成比例。Javadoc说“index索引到列表中的操作将从开头或结尾遍历列表,以较近者为准”,因此这些方法平均为O(n)(n / 4步),但O(1)为index = 0。

ArrayList<E>另一方面,允许快速随机读取访问,因此您可以在恒定时间内获取任何元素。但是,除了末端之外的任何地方添加或移除都需要将所有后面的元素移位,以便打开或填补空白。此外,如果您比下面阵列的容量添加更多的元件,一个新的数组(1.5倍的尺寸)被分配,而旧的阵列被复制到新的一个,因此添加到ArrayList是O(n)的在最坏的情况但平均不变。

因此,根据您打算执行的操作,您应该相应地选择实现。迭代任何一种List实际上同样成本。(迭代一个ArrayList从技术上更快,但除非你做的事情对性能非常敏感,否则你不应该担心这一点 - 它们都是常量。)

使用LinkedList的主要好处是当您重复使用现有迭代器来插入和删除元素时,因为这些操作的时间复制度是O(1)完成这些操作。在数组列表中,需要移动(即复制)数组的其余部分。另一方面,在最坏情况下LinkedList在O(n)(n / 2步)中的链接之后寻找,而在ArrayList期望的位置可以在数学上计算并在O(1)中访问。

使用的另一个好处LinkedList出现当您添加或从列表中的头去掉,因为这些操作是O(1) ,而ArrayList则是为O(n)。请注意,这ArrayDeque可能是LinkedList添加和删​​除头部的一个很好的替代方案,但它不是一个List。

此外,如果您有大型列表,请记住内存使用情况也不同。一个LinkedList的每个元素都有更多的开销,因为还存储了指向下一个和前一个元素的指针。ArrayLists没有这个开销。但是,ArrayLists无论是否实际添加了元素,都会占用为容量分配的内存。

一个默认初始容量ArrayList非常小(Java 1.4中的10 - 1.8)。但由于底层实现是一个数组,因此如果添加大量元素,则必须调整数组大小。当您知道要添加大量元素时,为了避免调整大小的高成本,请构建ArrayList具有更高初始容量的内容

综上所述;
    链表优于数组:
    
        a)您需要从列表中进行恒定时间插入/删除(例如在时间可预测性非常关键的实时计算中)

        b)您不知道列表中有多少项。对于数组,如果数组变得太大,您可能需要重新声明和复制内存

        c)您不需要随机访问任何元素

        d)您希望能够在列表中间插入项目(例如优先级队列)
   
    数组优于链表:
    
        a)您需要索引/随机访问元素

        b)提前了解数组中元素的数量,以便为数组分配正确的内存量

        c)在按顺序迭代所有元素时需要速度。您可以在数组上使用指针数学来访问每个元素,而您需要根据链表中每个元素的指针查找节点,这可能会导致页面错误,从而导致性能下降。

        d)记忆是一个问题。填充数组占用的内存少于链表。数组中的每个元素都只是数据。每个链表节点都需要数据以及指向链表中其他元素的一个(或多个)指针。
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值