Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-04-23:谈谈ArrayList和LinkedList的区别?

MoJieBlog opened this issue · comments

2019-04-23:谈谈ArrayList和LinkedList的区别?

顾名思义,ArrayList是数据结构,LinkedList是链表结构,它两的数据结构不同、

ArrayList 为 数组结构,具有数组的基本特性, 查询快,增删除非是最后一个 否则需要更改其余数据的角标
LinkedList为双链表 具有链表的基本特性 , 但访问元素需要把指针移动到相应位置慢

  1. ArrayList是基于数组的数据结构,LinkedList是基于链表的数据结构。
  2. ArrayList适用于查询操作,LinkedList适用于插入和删除操作。

从源码角度分析ArrayList和LinkedList的区别 可以看看这部分的总结,持续更新中....

1.ArrayList是基于数组的数据结构,分配的是一段连续的内存空间。
新增数据的时候效率低,因为新增一个元素的时候都要考虑数组的容量,即扩容判断,而后进行新增元素;
修改数据同样根据index索引查找修改;
删除数据的时候效率低,因为是连续的内存空间,除删除最后一个元素外,删除任一元素都会使数组中的元素进行移动;
查找数据可根据index索引快速查找;
2.LinkedList是基于链表的数据结构
对比以上:
优点: 不需要考虑扩容的问题和连续的内存空间问题,在新增和删除的效率更好
缺点: 缺少了索引,降低了查找元素的效率,对应也降低了修改元素的效率

有不对的欢迎指正!!!

嗯嗯,楼上讲的很好,我对LinkedList做点补充,及说一下使用场景
LinkedList基于双向链表实现,但是因为双向链表本身使用了更多空间,所以也需要额外的指针进行操作。
当按下标访问元素时set(i,e)/get(i),需要遍历整个链表,遍历时,会先判断postion的大小是否大于size()的一半,如果是,則从尾部遍历,否则反之,从而优化效率。
插入修改时修改前后节点的指针,但除了在链表两头的操作以外,其余的操作都需要遍历链表才能移动到下标所指位置。
然后说一下他们的使用场景。
如果说需要插入元素很快,那么推荐使用LinkedList,原因是ArrayList需要判断扩容,如果扩容还需要copy原来的复制到新数组,这也就是最花时间的地方。LinkedList快是因为它有一个 加速 效果,也就是刚才补充的判断 postion下标大小的操作。
如果说需要访问比较快的话,那么推荐使用ArrayList,原因是ArrayList 内部是数组,获取元素,直接通过下标去拿,效率可见一般,而不是像LinkedList去遍历一遍。

@Petterpx 如果ArrayList和LinkedList都使用遍历去查找数据,不通过下标去拿,那个效率会好一些?

@Petterpx 如果ArrayList和LinkedList都使用遍历去查找数据,不通过下标去拿,那个效率会好一些?

首先这个问题的话,LinkedList使用数组模拟指针,来实现链表的方式,所以LinkedList每次都要去计算相应的位置,如果说都是去遍历,如果是使用迭代器遍历,那么ListkedList效率会优于ArrayList,因为ArrayList在通过迭代器遍历的时候需要先生成指针。
回到你的问题,如果他们都采用遍历去查找数据,这时候要考虑的是那种方式去遍历,迭代器,还是for each,因为for each是在迭代器的基础上封装的,所以效率会比迭代器慢一点。
综上比较的话,通过迭代器方式,LinkedList效率是优于ArrayList,这与他们的内部实现有关。
这里没有考虑for循环是因为for循环也就相当于通过下标来访问。
不知道这样的解释是否可以帮到你。

ArrayList

连续

你们跑过吗,100万add,时候