浅析Arraylist和LinkedList

ArrayList和LinkedList已经是老生常谈的问题了,由于太久之前看的源码,觉得最近有点不清晰了,就再次看了一遍源码,现在来记录一下区别与联系,以及一点底层实现。

简述

首先ArrayList底层是通过数组实现的,而LinkedList则是通过双向链表实现的,他们都是线程不安全的

都实现了List接口,规定了几个必须实现的方法add,contains,indexof,remove

一.ArrayList

ArrayList 成员变量
  • Object[] elementsData;
  • int size;
底层实现
  • get() 首先需要检查传入的index rangeCheck(index) 再返回数组在该index的值
  • add() 首先保证空间足够用,然后加入新的对象在数组的尾部 ensureCapacityInternal(size+1);
  • remove() 先检查index,然后计算出需要移动的数量,例如size=10,要删除index=5的元素,则需要移动后面的四个元素,然后调用System.arraycopy()方法,将数组的后面4个依次向前移动一位,然后将数组最后一位置为null。

二.LinkedList

LinkedList成员变量
  • size
  • Node first 记录第一 节点
  • Node last 记录最后一个节点
底层实现
  • get() 类似ArrayList 先检查index的合法性然后调用node(index) 方法
  • node() 方法在这里插入图片描述
    • 首先判断index是否小于size的一半,如果小于从前向后遍历,大于则从后向前遍历
  • add()方法,直接调用linklast() 方法在这里插入图片描述
  • remove()从头开始遍历链表,当找到要删除的节点,将他删除。删除的方法呢?将该节点的前后节点链接起来,

对比

由上面的常用方法可以发现

1.ArrayList使用数组存储元素,因此在查询时速度较快,直接返回该位置的元素即可,时间复杂度为O(1);而LinkedList使用双向链表存储元素,在查询时需要从头或者尾遍历至查询元素,时间复杂度为O(n/2);

2.还是因为存储方式的问题,ArrayList在插入或者删除时,需要移动插入位置之后的所有元素,因此速度较慢,时间复杂度为O(n)。而LinkedList只需要找到该位置,移动”指针”即可,时间复杂度为O(1)。

当你对列表更多的进行查询,即获取某个位置的元素时,应当优先使用ArrayList;当你对列表需要进行频繁的删除和增加,而很少使用查询时,优先使用LinkedList;

注意事项!

1.上述结论适用于普遍的情景,有些极端情况不一定符合。比如频繁的在数组结尾附近插入数据,ArrayList也快于LinkedList。

2.LinkedList使用的空间大于ArrayList,因为本质上,ArrayList在每个位置存储了元素,而LinkedList存储了元素+前面节点+后面节点。

扩容

ArrayList 每次扩容后的大小为之前的1.5倍。int newCapacity = oldCapacity + (oldCapacity >> 1);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ArrayListLinkedList是两种不同的数据结构实现。ArrayList是基于动态数组的数据结构,而LinkedList是基于双向链表的数据结构。它们在不同的操作上有不同的效率。 对于随机访问的get和set方法,ArrayList要优于LinkedList。因为ArrayList基于数组,获取任意元素的位置时间复杂度为O(1),而LinkedList基于链表,时间复杂度为O(n)。所以如果需要频繁进行随机访问操作,使用ArrayList会更高效。\[2\] 对于新增和删除操作add和remove,LinkedList比较占优势。因为如果ArrayList不是在尾部进行新增和删除时,数组会进行前移或后移,导致时间复杂度为O(n)。而LinkedList只需要修改prev和next指针,时间复杂度为O(1)。所以如果需要频繁进行新增和删除操作,使用LinkedList会更高效。\[2\] 另外,ArrayList的优点是可以按下标查询元素,而不需要遍历整个链表。相比之下,LinkedList需要对底层链表进行遍历才能找到指定下标的元素。所以在需要按下标查询元素的场景下,ArrayList更具优势。\[3\] 综上所述,ArrayListLinkedList在不同的操作上有不同的效率优势。根据具体的需求,选择合适的数据结构可以提高程序的效率。 #### 引用[.reference_title] - *1* *2* [JAVA中ArrayListLinkedList的区别](https://blog.csdn.net/m0_50373778/article/details/124480121)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ArrayListLinkedList区别?看完秒懂~](https://blog.csdn.net/m0_68103666/article/details/124105939)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值