Java集合方面的面试题:ArrayList和LinkedList有什么差别?分别适用于哪些场景?

List是封装了针对线性表操作的接口,ArrayList和LinkedList是在项目里用的比较多的两个实现类。我在面试时一般会问,它们两者有什么差别?很多人能回答说,ArrayList是基于数组实现,而LinkedList是基于双向链表实现。

学过数据结构的同学都知道,如果我们要查找数组里的某个元素,可以根据如下的公式很快地定位到该元素的位置。

第i号元素的位置 = 第0号元素的位置+(i-1)*每个元素的长度。

但数组不擅长添加和删除元素,比如要在长度是10000的数组里的500号位置添加一个元素,我们首先得让500到10000号元素都往后移动一位,先把500号位置腾出来,随后再添加。删除也是类似。

和数组相对应,链表比较擅长添加和删除元素(只需要更改其中一个元素的指针即可),但不擅长于定位(如果要找500号元素,就得从0号开始一个个找)。

这种说法应付面试尚可,但在实际项目里,往往没有单纯的添加(或删除)和单纯的查找操作,一般是两者配合使用。比如我们会在一个for循环里通过add方法从头开始在尾部添加元素,完成后在另个地方通过get方法从头开始获取元素,这两个动作往往会配对出现

那么在这种情况下,该选用哪种集合?下面我们来通过ListCompare.java来比较一下这两类List的各种性能,从而来归纳它们的使用场景。

1	//省略必要的import集合包的代码
2	public class ListCompare {	
3	//在尾部添加元素 
4		static void testAddatTail(List list,String type)	{
5			int size = 1000000;		
6			long start=System.currentTimeMillis();  		
7	     //通过for循环在尾部添加元数据
8			for(int i = 0;i

在下表3.1里,我们列出了在上述代码里定义的方法。

表3.1 针对两种不同集合对比测试方法归纳表

方法名

行数

动作

testAddatTail

第4到14行

通过for循环在尾部添加1000000个元素

testRandomSearch

第16到25行

从集合的随机位置拿元素,相当于随机查找

testAddatRandom

第27到35行

在集合的随机位置添加元素

在main函数的39和40行,我们定义了两种List,随后从42到47行,我们分别针对两种不同的List集合执行了对比测试方法,如果我们运行多次,输出的时间未必都相等,但从中我们能看到两者的对比,根据其中的一次运行结果,我们能整理出如下表3.2所示的结论。

表3.2 运行结果分析表

比较项

集合种类

运行时间

分析

在尾部添加

ArrayList

141

ArrayList是基于数组,和基于链表的ListedList相比,能很快地定位到尾部

LinkedList

219

在随机位置添加

ArrayList

938

这里包含查找位置和添加两个动作,查找时基于数组的ArrayList占优,添加时基于LinkedList占优,综合下来还是LinkedList占优

LinkedList

672

在随机位置查找

ArrayList

4109

基于数组的ArrayList很占优,相比基于链表的Linkedlist就需要消耗一定的代价了。

LinkedList

5828

也就是说,如果被问到这类问题,你可以说出如下的结论。

第一,如果我们就一次性地通过add从集合尾部添加元素,添加完成后我们也只需读取一次,那么建议使用ArrayList,因为从上表来看,它两个动作的运行时间总和要小于LinketList。

第二,如果要频繁地添加元素,或者在完成添加元素后会频繁地通过indexOf方法从集合里查找元素,可以使用LinketList,理由是它的随机添加和随机查找的总时间消耗要小于ArrayList。

第三,请记得,如果在代码里indexOf的操作过于频繁从而成为项目运行的瓶颈时,可以考虑后文里提到的HashMap对象。

此外,ArrayList和Linkedlist都是线程不安全的,别把这点说成是它们的差别。

  关于集合类的面试文章汇总:

Java集合方面的面试题:Set集合是如何判断重复

Java集合方面的面试题:对比ArrayList和Vector对象,分析Vector为什么不常用
Java集合方面的面试题:ArrayList和LinkedList有什么差别?分别适用于哪些场景?
Java集合方面的面试题:TreeSet、HashSet和LinkedHashSet的各自特点

Java集合方面的面试题:泛型的继承和通配符

Java集合方面的面试题大汇总

 这是我的公众号,其中包含了大量面试文章,同时我自己出了多本Python和Java方面的书籍,会定期在公众号里发书的电子版。请大家关注下我的公众号,谢谢了。

你可能感兴趣的:(面试,面试,java)