ArrayList&&LinkedList 性能比较

最近在对比List下的两大功臣,功臣之一为ArrayList;功臣之二为LinkedList;
通过这次再次深入理解,有了如下的几点重新价值观刷新:

  • 【插入】我们都知道因为ArrayList底层是数组实现的;LinkedList底层是链表实现的;所以对于新增数据而言,肯定是LinkedList性能远远高于ArrayList的性能;但实践结果并非如此,ArrayList的新增性能并不低,而且通过测试,其比LinkedList插入速度还快。(测试JDK版本 1.8)
  • 【获取】由于LinkedList是链表结构,没有角标的概念,没有实现RandomAccess接口,不具备随机元素访问功能,所以在get方面表现的差强人意,ArrayList再一次完胜。具体为何LinkedList会这么慢呢?其实是因为LinkedList是链表结构,没有角标的概念,没有实现RandomAccess接口,不具备随机元素访问功能,所以在get方面表现的差强人意
  • 【随机根据某个索引插入元素,到底谁快呢?】
    操作代码如下:
//迭代次数
	public static int ITERATION_NUM = 10000000;

	public static void main(String[] agrs) {
		insertPerformanceCompare();
	}

	//新增性能比较:
	public static void insertPerformanceCompare() {

		System.out.println("LinkedList新增测试开始");
		long start = System.nanoTime();
		List<Integer> linkedList = new LinkedList<Integer>();
		for (int x = 0; x < ITERATION_NUM; x++) {
			linkedList.add(x);
		}
		long end = System.nanoTime();
		System.out.println("linkedList time one:"+(end - start));
		long startInsert=System.nanoTime();
		//依次执行,看执行时间
		linkedList.add(0,11);
		linkedList.add(10,11);
		linkedList.add(100,11);
		linkedList.add(1000,11);
		linkedList.add(10000,11);
		linkedList.add(100000,11);
		linkedList.add(1000000,11);
		long endInsert=System.nanoTime();
		System.out.println("linkedList time two:"+(endInsert-startInsert));
		System.out.println("ArrayList新增测试开始");
		long startArray = System.nanoTime();
		List<Integer> arrayList = new ArrayList<Integer>();
		for (int x = 0; x < ITERATION_NUM; x++) {
			arrayList.add(x);
		}
		long endArray = System.nanoTime();
		System.out.println("arrayList time one:"+(endArray - startArray));

		long startArrayInsert=System.nanoTime();

		arrayList.add(0,11);
		arrayList.add(10,11);
		arrayList.add(100,11);
		arrayList.add(1000,11);
		arrayList.add(10000,11);
		arrayList.add(100000,11);
		arrayList.add(1000000,11);
		long endArrayInsert=System.nanoTime();
		System.out.println("arrayList time two:"+(endArrayInsert-startArrayInsert));
	}
index insert ArrayList LinkedList
0 3646828 33657
10 3670657 33118
100 3628176 33256
1000 3270814 44075
10000 3696530 128725
100000 3656730 1010909
1000000 3606553 10099185
  • 【随机删除某一个位置的元素,到底谁快呢?】

remove关键代码

		linkedList.remove(0);
		linkedList.remove(10);
		linkedList.remove(100);
		linkedList.remove(1000);
		linkedList.remove(10000);
		linkedList.remove(100000);
		linkedList.remove(1000000);

		arrayList.remove(0);
		arrayList.remove(10);
		arrayList.remove(100);
		arrayList.remove(1000);
		arrayList.remove(10000);
		arrayList.remove(100000);
		arrayList.remove(1000000);

index del ArrayList LinkedList
0 3319289 16816
10 3796653 17964
100 3462862 19898
1000 3474424 27497
10000 3320296 113838
100000 3312930 1803475
1000000 3029520 10050950

当看到如上数据时,不知道第一感是作何感受?其实当理解了其底层实现的时候,就不吃惊了。
通过如上数据可以发现,对于ArrayList而言,其不管是通过索引增加到哪个位置还是移除某个元素,其用的时间都是均等的;而对于LinkedList而言,则随着索引的增加用的时间逐渐增大。所以以上得到结论:

  • void add(int index, E element) 当数据量超过6位数之后,则考虑使用ArrayList吧
  • E remove(int index) 当数据量超过6位数之后,则考虑使用ArrayList吧

为何会出现这么大的差距呢?上述文章中我们曾提到过,对于ArrayList而言,因为其实现了RandomAccess,有了快速随机访问存储元素的功能,所以只要是通过索引的操作,其都是通过角标实现的,进而不用遍历整个集合,所以效率更高。

posted on 2018-11-09 10:09  huohuoL  阅读(146)  评论(0编辑  收藏  举报

导航