java集合之ArrayDeque(3)

ArrayDeque介绍

原文地址:arrayDeque

ArrayDeque和LinkedList是Deque(double ended queue)的两个通用实现,官方更推荐使用AarryDeque用作栈和队列。

从名字可以看出ArrayDeque底层通过数组实现,为了满足可以同时在数组两端插入或删除元素的需求,该数组还必须是循环的,即循环数组(circular array),也就是说数组的任何一点都可能被看作起点或者终点。ArrayDeque是非线程安全的(not thread-safe),当多个线程同时使用的时候,需要程序员手动同步;另外,该容器不允许放入null元素。

从图中可以看出head指向第一个有效元素,tail指向最后一个有效元素,所以head不一定等于0,tail也不一定大于head。

方法剖析

addFirst(E e) :在对首插入一个元素,即head前添加一个元素

public void addFirst(E e) {
    if (e == null)//不允许放入null
        throw new NullPointerException();
    elements[head = (head - 1) & (elements.length - 1)] = e;//2.下标是否越界
    if (head == tail)//1.空间是否够用
        doubleCapacity();//扩容
}

注:有序在判断head-1是否越界时,可能存在head-1为负数的情况,所以(head-1) & (elements.length-1)既可以判断数组是否越界,也可以解决为负数的情况因为elements.length必需是2的指数倍,elements - 1就是二进制低位全1,跟head - 1相与之后就起到了取模的作用,如果head - 1为负数(其实只可能是-1),则相当于对其取相对于elements.length的补码。

如果空间不足,会调用扩容函数扩容

//doubleCapacity()
private void doubleCapacity() {
    assert head == tail;
    int p = head;
    int n = elements.length;
    int r = n - p; // head右边元素的个数
    int newCapacity = n << 1;//原空间的2倍
    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;
}

注:扩容后满足head == 0 ,head < tail (扩容后是原来的2倍)

addLast(E e):向tail后一个位置插入元素,同样容量不足,扩容。

pollFirst():作用是删除并返回Deque首端元素,也即是head位置处的元素。如果容器不空,只需要直接返回elements[head]即可,当然还需要处理下标的问题。由于ArrayDeque中不允许放入null,当elements[head] == null时,意味着容器为空。

public E pollFirst() {
    E result = elements[head];
    if (result == null)//null值意味着deque为空
        return null;
    elements[h] = null;//let GC work
    head = (head + 1) & (elements.length - 1);//下标越界处理
    return result;
}

pollLast:删除并返回Deque尾端元素,也即是tail位置前面的那个元素.

peekFirst():返回但不删除Deque首端元素,也即是head位置处的元素,直接返回elements[head]即可。

peekLast():返回但不删除Deque尾端元素,也即是tail位置前面的那个元素。

posted @ 2018-11-28 10:39  楠木(鱼摆摆)  阅读(273)  评论(0)    收藏  举报