ArrayDeque源码解析

ArrayDeque是一个双端队列,它是线程不安全的,不能插入null元素,当使用栈时比Stack要快,当使用队列时比LinkedList要快。

先初始化一个一定大小的数组,大小是2的n次方,接下来看下添加的源码。

public void addFirst(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[head = (head - 1) & (elements.length - 1)] = e;
        //head ,和tail开始都是0,当下次再相同时,说明数组满了,需要扩展了
        if (head == tail)
            doubleCapacity();
    }

head = (head - 1) & (elements.length - 1),当第一次添加时head变成数组的最后一个元素,以后每次减一。
添加一个元素后的图如下
插入一个元素后
接下来看扩容的源码

private void doubleCapacity() {
        assert head == tail;
        int p = head;
        int n = elements.length;
        int r = n - p; // number of elements to the right of p
        int newCapacity = n << 1;
        if (newCapacity < 0)
            throw new IllegalStateException("Sorry, deque too big");
        Object[] a = new Object[newCapacity];
        System.arraycopy(elements, p, a, 0, r);
        System.arraycopy(elements, 0, a, r, p);
        elements = (E[])a;
        head = 0;
        tail = n;
    }

将老数组复制到新的数组中,
接下来看addLast

public void addLast(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[tail] = e;
        //保证tail正向增长
        if ( (tail = (tail + 1) & (elements.length - 1)) == head)
            doubleCapacity();
    }

pollFirst()返回第一个元素,并删除

public E pollFirst() {
        int h = head;
        E result = elements[h]; // Element is null if deque empty
        if (result == null)
            return null;
        elements[h] = null;     // Must null out slot
        //将head增长一个,如果没元素就是0
        head = (h + 1) & (elements.length - 1);
        return result;
    }

其它的几个增删就和上面的几个方法类似,我就不再写了。

说说ArrayDeque和Stack和LindedList的对比

Stack是继承的vector里面很多方法都是同步的,所以比ArrayDeque慢,而且有很多vector的方法。LindedList作为队列在增加和删除的时候需要移动指针,需要再开辟空间。ArrayDeque很多时候不需要从扩大,这也是ArrayDeque性能较好的原因吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久梦歌行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值