ArrayList和LinkedList

ArrayList和LinkedList的新增性能分析

各自的特点

  • ArrayList适合场景是【查询】、【检索】比较快,底层实现是动态的Node数组(顺序表)
  • LinkedList适合的场景是【修改】【删除】【增加】元素(链表)

注意的地方

  • 初始化各自的时,增加元素,ArrayList的add方法默认是在末尾添加,LinkedList默认也是在末尾添加,到底谁快呢,我们测试一下:
    【在列表末尾增加数据】
列表大小ArrayListLinkedList
100004ms1ms
10000012ms8ms
100000047ms164ms
100000003261ms6135ms
10000000047157msxxxms

【我的看法】:
为什么在容量小的情况下ArrayList会比Linkedlist慢?我打开源码原来如此,ArrayList在add(E e)的方法是在列表末尾添加要做的事就是,检查是否达到一定的容量,然后决定数组扩容(拷贝数组啊,数组的空间一旦分配不能改变啊!2333),LinkedList的呢?add(E e)方法,直接在last节点添加,所以快啊,当容量大的适合,LindedList力不从心,时间都消耗在new Node()上面,所以时间复杂度升高了。贴一下相关的代码吧

LinkedList的add(E e)方法
 		void linkLast(E e) {
 			final Node<E> l = last;
        	final Node<E> newNode = new Node<>(l, e, null);//就是在这里new,
        	last = newNode;
        	if (l == null)
            	first = newNode;
        	else
            	l.next = newNode;//引用
        	size++;
        	modCount++;
         }
ArrayList的add(E e)方法
 public boolean add(E e) {
 		/*
 		Increments modCount!! 这里就是检查空间,
 		拷贝数组,分配空间,具体的,我也没细看
        */
        ensureCapacityInternal(size + 1);  
        elementData[size++] = e; //这里当然快 比new 是不是快多了
        return true;
    }
总结
  1. 使用add(E e)方法的时候,ArrayList前期可能比LinkedList慢,是因为要检查一大堆东西的嘛,可能到了越来越多的东西加进来后,LinkedList不断的new 对象,而ArrayList已经开辟好了数组空间,直接赋索引就可以,那就变快了,这仅仅只是末尾添加元素,ArrayList并没有移动数组啥子的
  2. 当使用add(int index, E element)方法的时候,在指定的位置插入元素,这个时候会不一样;看下面的测试结果
测试的代码

public class AnalyzeList {

    private static final int MAXSIZE = 1000000; //最大元素个数 手动修改

    private static final int MAX_RANDOM = 10000;//最大的随机数

    public static void main(String[] args) {
        List<Integer> arrayList = new ArrayList<>();
        List<Integer> linkedList = new LinkedList<>();

        Random random = new Random();
        long startTime1 = System.currentTimeMillis();
        System.out.println("======arrayList开始增加元素======");
        for (int i = 0; i < MAXSIZE; i++) {
            arrayList.add(0,new Integer(random.nextInt(MAX_RANDOM)));
        }
        System.out.println("======arrayList停止添加元素======");
        System.out.println("arrayList在末尾添加元素("+MAXSIZE+"个)耗时(ms) : "+(System.currentTimeMillis()-startTime1));
        System.out.println("arrayList的大小" + arrayList.size());

        System.out.println();
        System.out.println();
        long startTime2 = System.currentTimeMillis();
        System.out.println("======linkedList开始增加元素======");
        for (int i = 0; i < MAXSIZE; i++) {
            linkedList.add(0,new Integer(random.nextInt(MAX_RANDOM)));
        }
        System.out.println("======linkedList停止添加元素======");
        System.out.println("linkedList在末尾添加元素("+MAXSIZE+"个)耗时(ms) : "+(System.currentTimeMillis()-startTime2));
        System.out.println("linkedList的大小" + linkedList.size());


    }
}

【在指定的位置增加数据】
初始的容量大小都为100W的数据吧,我们分别在首位,中间,末尾插入元素,看一下测试情况

列表大小ArrayListLinkedList
10000
first3825ms2ms
middle734ms39432ms
last1ms1ms
100000
first15278ms7ms
middle6910msXXXXXms
last5ms3ms
1000000
firstXXXms7ms
middle12msXXXXms
lastmsms
10000000
firstmsms
middlemsms
lastmsms
总结

1.在指定位置(非末尾)插入时,arrayList需要范围检查是否开辟新空间数组拷贝等一系列操作,最麻烦的就是在最初的要拷贝的内容少,插入位置越靠后,拷贝数组就越耗时;linkedList插入要遍历起始位置到索引的位置,所以越靠前,时间消耗越短,越靠后插入的索引,遍历的距离就越远,时间开销就大

测试代码

public class AnalyzeList {

    private static final int INITSIZE = 1000000; //初始化大小

    private static final int MAX_RANDOM = 10000;//最大的随机数

    private static final int ADDED_SIZE = 1000000;//插入的的元素个数

    private static final int INSERT_INDEX = INITSIZE/2;//插入的位置


    public static void main(String[] args) {
        List<Integer> arrayList = new ArrayList<>();
        List<Integer> linkedList = new LinkedList<>();

        Random random = new Random();
        for (int i = 0; i < INITSIZE; i++) {
            arrayList.add(new Integer(random.nextInt(MAX_RANDOM)));
        }
        System.out.println("arrayList的大小" + arrayList.size());

        System.out.println();
        System.out.println();
        for (int i = 0; i < INITSIZE; i++) {
            linkedList.add(new Integer(random.nextInt(MAX_RANDOM)));
        }
        System.out.println("linkedList的大小" + linkedList.size());


        long start1 = System.currentTimeMillis();
        System.out.println("arrayList ==============");

        System.out.println("arrayList 开始插入数据");
        for (int i = 0; i < ADDED_SIZE; i++) {
            arrayList.add(INSERT_INDEX,new Integer(random.nextInt(MAX_RANDOM)));
        }
        System.out.println("arrayList 结束插入数据");
        System.out.println("arrayList 插入数据用时" + (System.currentTimeMillis() - start1));
        System.out.println("arrayList ==============");

        System.out.println("");
        System.out.println("");

        System.out.println("linkedList ==============");
        long start2= System.currentTimeMillis();
        System.out.println("linkedList 开始插入数据");
        for (int i = 0; i < ADDED_SIZE; i++) {
            linkedList.add(INSERT_INDEX,new Integer(random.nextInt(MAX_RANDOM)));
        }
        System.out.println("linkedList 结束插入数据");
        System.out.println("linkedList 插入数据用时" + (System.currentTimeMillis() - start2));
        System.out.println("linkedList ==============");

    }
}

写在后面

不要觉得哪个性能查询就一定快 ,哪个插入数据就一定快,具体情况具体分析,忘记了 get方法,当然是 arraylist快,LinkedList的get我估摸着要去从头开始查找

待更新==================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值