ArrayList与LinkedList

ArrayList底层基于数组实现,LinkedList底层是基于双向链表实现的

对于随机访问时ArrayList优于LinkedList

对于插入删除操作LinkedList优于ArrayList

ArrayList的扩容机制

ArrayList在用默认方法构造时初始容量为10,如果使用参数构造时则初始容量为指定的

ArrayList的扩容方法主要是在add方法中调用,ArrayList的扩容是通过ensureExplicitCapaCity的方法去判断是否需要扩容的,如果需要扩容则调用grow方法对ArrayList进行扩容,扩容时该方法会将AarryList扩容至原始容量的1.5倍,然后将原来ArrayList的元素复制到新的ArrayList中。下面为grow方法的源码:

    private void grow(int minCapacity) {

        // overflow-conscious code

        int oldCapacity = elementData.length;

        int newCapacity = oldCapacity + (oldCapacity >> 1);

        if (newCapacity - minCapacity < 0)

            newCapacity = minCapacity;

        if (newCapacity - MAX_ARRAY_SIZE > 0)

            newCapacity = hugeCapacity(minCapacity);

        // minCapacity is usually close to size, so this is a win:

        elementData = Arrays.copyOf(elementData, newCapacity);

   }

LinkedList基于链表实现就没有什么扩容机制了,但是链表底层使用JNI方法进行创建节点

回答:话说数组增删慢,链表增删快,为什么这个输出耗时链表的时间反而多呢?有谁能解释一下呢?这样的疑问

 

本题中ArrrayList将要被扩容30多次,而LinkedList则要创建1000000个节点这就可以对比出效果了,LinkedList创建了节点在就局部性上来说是比较差的,cache的命中率是不高的。

就ArrayList中的add方法而言如果在没有扩容的情况下插入数据的时间复杂度为o(1),如果涉及到扩容它的时间复杂度则由Arrays.copyof()方法的时间复杂度决定

就增删快和查询快应该是建立在已经拥有一个ArrayList和LinkedList且里面是有数据,对里面数据需要修改时的结论,而不是目前这样,如果要进一步测试这个结论还需要以下的代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class ArrayListandLinkList {
    public static void main(String[] args) {
        ArrayList arrayList =new ArrayList();
        LinkedList linkedList =new LinkedList();
        for(int i=0;i<10000;i++){
            arrayList.add(i);
            linkedList.add(i);
        }
        System.out.println("ArrayList调用add方法:"+getTime());
        System.out.println("LinkedList调用add方法:"+getTime1());
        System.out.println("LinkedList头插法:"+getTime2());
        System.out.println("LinkedList尾插法:"+getTime6());
        System.out.println("LinkedList0处添加" + getTime7());
        System.out.println("ArrayList按位置插入:"+getTime3());
        System.out.println("ArrayList访问时间:"+getTime4(arrayList));
        System.out.println("LinkedList访问时间:"+getTime4(linkedList));
        System.out.println("ArrayList插入时间:"+getTime5(arrayList));
        System.out.println("LinkedList插入时间:"+getTime5(linkedList));
    }
    public static long getTime(){
        long millis = System.currentTimeMillis();
        ArrayList arrayList =new ArrayList();
        for(int i=0;i<1000000;i++){
            arrayList.add(i);
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
    public static long getTime3(){
        long millis = System.currentTimeMillis();
        ArrayList arrayList =new ArrayList();
        for(int i=0;i<1000000;i++){
            arrayList.add(i,i);
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
    public static long getTime1(){
        long millis = System.currentTimeMillis();
        LinkedList linkedList =new LinkedList();
        for(int i=0;i<1000000;i++){
            linkedList.add(i);
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
    public static long getTime2(){
        long millis = System.currentTimeMillis();

        LinkedList linkedList =new LinkedList();
        for(int i=0;i<1000000;i++){
            linkedList.addFirst(i);
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
    public static long getTime4(List list){
        long millis = System.currentTimeMillis();
        for(int i=0;i<10000;i++){
            int index=Collections.binarySearch(list,list.get(i));
            if(index!=i){
                System.out.println("Error");
            }
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
    public static long getTime5(List list){
        long millis = System.currentTimeMillis();
        for(int i=100;i<10000;i++){
             list.add(10,i);
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
    public static long getTime6(){
        long millis = System.currentTimeMillis();

        LinkedList linkedList =new LinkedList();
        for(int i=0;i<1000000;i++){
            linkedList.addLast(i);
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
    public static long getTime7(){
        long millis = System.currentTimeMillis();

        LinkedList linkedList =new LinkedList();
        for(int i=0;i<1000000;i++){
            linkedList.add(0,i);
        }
        long millis1= System.currentTimeMillis();
        long time=millis1-millis;
        return time;
    }
}

测试结果:

根据上述代码的测试就更加印证了LinkedList比ArrayList增加快,ArrayList比LinkedList访问快的说法,删除的话有兴趣的可以进行自测。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值