Java数据结构详解(十)-ArrayDeque

ArrayDeque

ArrayDeque是一个循环数组.只要数组不被填满,ArrayDeque就可以不用扩容.组的任何一点都可能被看作起点或者终点.

ArrayDeque是Deque 接口的大小可变数组的实现。数组双端队列没有容量限制;它们可根据需要增加以支持使用。它们不是线程安全的;在没有外部同步时,它们不支持多个线程的并发访问。禁止 null 元素。此类很可能在用作堆栈时快于 Stack,在用作队列时快于 LinkedList。

大多数 ArrayDeque 操作以摊销的固定时间运行。异常包括 remove、removeFirstOccurrence、removeLastOccurrence、contains、iterator.remove() 以及批量操作,它们均以线性时间运行。


ArrayDeque 字段

//底层数组
transient Object[] elements; 

//头部指针
transient int head;

//尾部指针
transient int tail;

//初始化的最小容量
private static final int MIN_INITIAL_CAPACITY = 8;

ArrayDeque 的构造方法

无参构造器

    public ArrayDeque() {

        //构造一个空数组deque,初始容量足以容纳16个元素
        elements = new Object[16];
    }

有参数的构造器

    public ArrayDeque(int numElements) {

        //构造一个空数组deque,初始容量足以容纳指定数量的元素
        allocateElements(numElements);
    }
    public ArrayDeque(Collection<? extends E> c) {
        allocateElements(c.size());
        addAll(c);
    }

    private void allocateElements(int numElements) {
        int initialCapacity = MIN_INITIAL_CAPACITY;
        // Find the best power of two to hold elements.
        // Tests "<=" because arrays aren't kept full.
        if (numElements >= initialCapacity) {
            initialCapacity = numElements;
            initialCapacity |= (initialCapacity >>>  1);
            initialCapacity |= (initialCapacity >>>  2);
            initialCapacity |= (initialCapacity >>>  4);
            initialCapacity |= (initialCapacity >>>  8);
            initialCapacity |= (initialCapacity >>> 16);
            initialCapacity++;

            if (initialCapacity < 0)   // Too many elements, must back off
                initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
        }
        elements = new Object[initialCapacity];
    }

ArrayDeque 被用作队列时的方法

addLast(e)

    public void addLast(E e) {

        //e为null时 抛出异常.
        if (e == null)
            throw new NullPointerException();

        //在尾部位置添加e.
        elements[tail] = e;

        //下标是否越界
        if ( (tail = (tail + 1) & (elements.length - 1)) == head)
            //扩容
            doubleCapacity();
    }

offerLast(e)

    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }

pollFirst

    public E pollFirst() {
        int h = head;
        @SuppressWarnings("unchecked")
        E result = (E) elements[h];
        // Element is null if deque empty
        if (result == null)
            return null;
        elements[h] = null;     // Must null out slot
        head = (h + 1) & (elements.length - 1);
        return result;
    }

removeFirst()

    public E removeFirst() {
        E x = pollFirst();
        if (x == null)
            throw new NoSuchElementException();
        return x;
    }

element()

    public E element() {
        return getFirst();
    }

peekFirst()

    @SuppressWarnings("unchecked")
    public E peekFirst() {
        // elements[head] is null if deque empty
        return (E) elements[head];
    }

peek

    public E peek() {
        return peekFirst();
    }

    //扩容方法,容量是原来的两倍
    private void doubleCapacity() {

        //保证Boolean表达式为 TRUE ,如果为FALSE则抛出异常;
        assert head == tail;
        int p = head;
        int n = elements.length;

        //计算head右边的元素个数
        int r = n - p; // number of elements to the right of p

        //newCapacity = n * 2  容量为原来的两倍
        int newCapacity = n << 1;
        if (newCapacity < 0)
            throw new IllegalStateException("Sorry, deque too big");

        new一个容量为原来数组容量两倍的新数组.
        Object[] a = new Object[newCapacity];

        //这里用了两次数组复制.目的是为了把原来的循环数组的数据展开.
        System.arraycopy(elements, p, a, 0, r);
        System.arraycopy(elements, 0, a, r, p);
        elements = a;
        head = 0;
        tail = n;
    }

ArrayDeque 被用作堆栈时的方法

push(e)

    public void push(E e) {
        addFirst(e);
    }

addFirst

    public void addFirst(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[head = (head - 1) & (elements.length - 1)] = e;
        if (head == tail)
            doubleCapacity();
    }

pop()

    public E pop() {
        return removeFirst();
    }

removeFirst

    public E removeFirst() {
        E x = pollFirst();
        if (x == null)
            throw new NoSuchElementException();
        return x;
    }

peek()

    public E peek() {
        return peekFirst();
    }

peekFirst()

    @SuppressWarnings("unchecked")
    public E peekFirst() {
        // elements[head] is null if deque empty
        return (E) elements[head];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值