ArrayDeque——循环数组之找下一个元素的正确位置

版权声明:转载请注明出处 https://blog.csdn.net/wang_8101/article/details/82963427

ArrayDeque——循环数组之找下一个元素的正确位置

内部的实例变量:

private transient E[] elements; // 用于存储元素的数组
privata transient int head; // 头
privata transient int tail; // 尾

如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。

构造方法(其一)

public ArrayDeque(Collection<? extends E> c){

	allocateElements(c.size); // 该方法用于计算该分配的数组的长度

	addAll(c);


allocateElements(int numElements)

该方法计算逻辑:

  1. 如果numElements小于8,就是8

  2. 如果numElements大于等于8,分配的实际长度是严格大于numElements并且为2的整数次幂的最小数。比如:numElements为10,则实际分配16,如果numElements为32则为64。

    是2的幂次数,是为了更有效率的获取数组中下一个元素的正确位置。严格大于numElements,是因为循环数组必须时刻至少留一个空位,tail指向下一个空位,为了容纳numElements个元素,至少需要numElements+1个位置

addAll(E e)

addAll只是循环调用了add方法;

add:

public boolan add(E e){
    addLast(e);
    return true;
}

addLast(E e)

public void addLast(E e){
    if(e == null)
    	throw new NullPointerException();
    elements[tail] = e; // 将元素添加到tail处
    if((tail = (tail +1 ) & (element.length-1)) == head)
    	doubleCapacity
}

  1. tail = (tail +1 ) & (element.length-1)—— 将tail指向下一个位置(tail的下一个位置是 (tail +1 ) & (element.length-1))
  2. (tail = (tail +1 ) & (element.length-1)) == head 时说明队列满了

神奇的操作:

进行与操作保证了索引在正确范围,与(element.length-1)相与就可以得到下一个正确位置,是因为elements.length时2的幂次方,(element.length-1)的后几位全是1,无论是证书还是附属,与(element.length-1)相与都能得到期望的下一个正确位置;

这种操作是循环数组中的常见操作,效率很高。

ps:与操作:将数转换为二进制,都为1时为1,其他情况都为0,得到值后再转为10进制

如:elements.length = 8,则(element.length-1) = 7,二进制为0111,对于8,与7相与,结果为0.

猜你喜欢

转载自blog.csdn.net/wang_8101/article/details/82963427