暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用ArrayList还是LinkedList?

这个码农有点帅 2021-06-21
310

集合类型是Java开发中使用最频繁的对象类型之一,JDK也针对不同场景提供了很多集合类型,关于ArrayList、LinkedList和Vector的区别也始终是Java面试的常见问题。


在面试中,发现大部分人都能回答出:

  • ArrayList和Vector都采用数组方式存储数据。数组存储区间是连续的,占用内存大。

  • ArrayList和Vector都可以通过下标直接索引元素,所以查询比较快。但插入或删除数据涉及到数组元素地移动等内存操作,所以插入数据慢(插入或删除数组最后一个元素不涉及元素移动,时间为O(1))。

  • Vector是同步的,即线程安全的(synchronized),而ArrayList是异步的,所以Vector性能比ArrayList要差。

  • Vector和ArrayList在超出长度需要扩展内部数组长度时,Vector默认自动增长原来的一倍的数组长度,而ArrayList增长原来的50%。所以如要要保存大量的数据使用Vector更好,因为可以通过设置集合的初始化大小来避免不必要的资源开销。

  • LinkedList使用双向链表实现存储,链表存储区间离散,占用内存小。

  • 链表按序号索引需要向前或向后遍历,但插入数据时只需记录插入记录的前后项即可,所以LinkedList插入数据快但查询慢。

  • 对于需要快速插入、删除元素,应该使用LinkedList。如果需要快速随机查询元素,应该使用ArrayList。

这些回答是否准确呢?ArrayList 和 Vector 使用了数组实现,这两者的实现原理差不多,LinkedList 使用了双向链表实现。下面分析下 有哪些因素会影响ArrayList 和 LinkedList 的效率。


ArrayList

ArrayList继承AbstractList抽象类,实现了List<E>, RandomAccess, Cloneable, java.io.Serializable接口。实现RandomAccess接口表示可快速随机访问;实现Cloneable接口表示可克隆;实现Serializable接口表示可序列化。


初始化

当ArrayList新增元素时,如果所存储的元素已经超过数组大小,就会进行动态扩容,数组的扩容会导致整个数组进行一次内存复制。频繁扩容势必导致效率的降低,因此,在初始化ArrayList时,可以通过构造函数预先指定数组大小,减少扩容次数,从而提高效率。


增删元素

ArrayList 添加元素有两种方法:一种是直接将元素加到末尾,另外一种是添加元素到指定位置。

如果只在数组末尾添加元素,在不发生动态扩容的情况下,即使添加大量元素,ArrayList性能也不会变差,甚至比其他List集合的性能还要好。

如果添加元素到指定位置,除非添加到数组末尾,否则会导致指定位置之后的所有元素都需要动态后移,势必导致性能下降。

ArrayList删除元素和添加元素原理类似,删除元素后都要进行元素移动。删除元素位置越靠前,移动元素越多,性能开销越大。


遍历元素

ArrayList是基于数组实现的,所以可以通过下标非常快速地获取元素。


LinkedList

LinkedList 是基于双向链表数据结构实现的,定义了一个 Node数据结构,Node数据结构中包含了 3 个部分:元素内容 item、前指针 prev 、后指针 next。


初始化

LinkedList是链表数据结构,无需初始化。


增删元素

LinkedList添加元素也有两种方法:直接添加至末尾 和 添加到指定位置。LinkedList添加元素只需改变前后元素的指针,所以相对ArrayList添加操作而言,LinkedList添加元素性能更好。

LinkedList删除元素时,需要先找到元素。如果要删除的元素位置在链表的前半段,则从前往后查找;如果在链表的后半段,则从后往前查找。所以,LinkedList删除靠前或靠后的元素都非常高效。但是,如果链表有大量元素,需要删除的元素又处于中间位置,则需要查找比对多次,效率会变差。


遍历元素

LinkedList获取元素和删除元素原理相似,通过分前后半段循环查找到对应元素。但是这种方式查询元素效率很低,特别是用for循环遍历的情况下,每次查找都需要遍历半个链表(分从前或从后查找)。不过,可以通过迭代器iterator遍历元素,不需要循环查找链表。通过实验可以发现,LinkedList的迭代循环和ArrayList的迭代循环性能相当,所以在遍历LinkedList时,切忌使用for循环。


通过上面的分析,对于“LinkedList新增、删除元素更快,ArrayList查询效率更高”,还会表示赞同吗?



文章转载自这个码农有点帅,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论