黑马程序员-Java中ArrayList和LinkedList区别

ArrayList和LinkedList的大致区别:

  1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
  2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 

  3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用(references)。例如我们可以用ArrayList来存储一系列的String或者Integer。那么ArrayList和LinkedList在性能上有什么差别呢?什么时候应该用ArrayList什么时候又该用LinkedList呢?

 

一、 时间复杂度

ArrayList的内部实现是基于数组对象的,因此,它使用get方法访问随机元素要比LinkedList快很多而LinkedList的get方法相当于遍历查找。

	public void LinkedListInsert(){
		linkedlist = new LinkedList();
		start = System.currentTimeMillis();
		for(int i = 0; i < 1000000; i++){
			linkedlist.add("hello itheima");
		}
		end = System.currentTimeMillis();
		
		System.out.println("LinkedList insert time: " + (end - start));
	}
	
	//测试ArrayList插入时间
	public void ArrayListInsert(){
		arraylist = new ArrayList();
		start = System.currentTimeMillis();
		for(int i = 0; i < 1000000; i++){
			arraylist.add("hello itheima");
		}
		end = System.currentTimeMillis();
		
		System.out.println("ArrayList insert time: " + (end - start));
	}

  测试结果:

LinkedList insert time: 109
ArrayList insert time: 94

  这个时间是不固定的,当一个元素被加到ArrayList的最开端时,所有已经存在的元素都会后移,这就意味着数据移动和复制上的开销。相反的,将一个元素加到LinkedList的最开端只是简单的未这个元素分配一个记录,然后调整两个连接。在LinkedList的开端增加一个元素的开销是固定的,而在ArrayList的开端增加一个元素的开销是与ArrayList的大小成比例的。

	//测试LinkedList删除时间
	public void LinkedListDelete(){
		start = System.currentTimeMillis();
		for(int i = 999999; i >= 0; i--){
			linkedlist.remove(i);
		}
		end = System.currentTimeMillis();
		
		System.out.println("LinkedList delete time: " + (end - start));
	}
	
	//测试ArrayList删除时间
	public void ArrayListDelete(){
		start = System.currentTimeMillis();
		for(int i = 999999; i >= 0; i--){
			arraylist.remove(i);
		}
		end = System.currentTimeMillis();
		
		System.out.println("ArrayList delete time: " + (end - start));
	}

  测试结果:

LinkedList delete time: 31
ArrayList delete time: 16

  程序中的删除是从尾部顺序删除,所以ArrayList的删除速度反而快,但是现实当中,如果说批量的随机删除,LinkedList的优势就会体现出来。

二、 空间复杂度

LinkedList中有一个私有的内部类,所有除了存放数据外,还要额外的空间存放内部类中其他对象。ArrayList使用内置数组存储元素,容量算法:新容量=(旧容量*3)/2+1,也就是说每一次容量大概会增长50%,所以往往存在空间浪费的情况,如果你有一个包含大量元素的ArrayList对象,那么最终将有很大的空间会被浪费掉,这个浪费是由ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素,数组将不得不被重新进行分配以便能够增加新的元素。对数组进行重新分配,将会导致性能急剧下降。但是我们可以通过trimToSize方法在ArrayList分配完毕之后去掉浪费掉的空间。

 

总结:

ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下: 
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。

2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。

3.LinkedList不支持高效的随机元素访问。

4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。

 

可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。

posted @ 2015-06-01 13:12  troy健  阅读(273)  评论(0编辑  收藏  举报