ArrayDeque简介说明

戚薇 Java教程 发布时间:2022-07-08 22:40:40 阅读数:4132 1
下文笔者讲述ArrayDeque简介说明

ArrayDeque简介

ArrayDeque是Deque接口的一种实现
依赖于可变数组来实现的
ArrayDeque没有容量限制,可根据需求自动进行扩容
ArrayDeque可作为栈来使用,效率要高于Stack
ArrayDeque可以作为队列来使用,效率相较于基于双向链表的Linkedlist也要更好一些

ArrayDeque的成员变量

	//数组存储元素
	transient Object[] elements;
	//头部元素索引
	transient int head;
	//尾部元素索引
	transient int tail;
	//最小容量
	private static final int MIN_INITIAL_CAPACITY = 8;
ArrayDeque底层使用数组存储元素
  同时还使用head和tail来表示索引
  但注意tail不是尾部元素的索引
   而是尾部元素的下一位
即下一个将要被加入的元素的索引

ArrayDeque如何初始化

public ArrayDeque() {
    elements = new Object[16];
}

public ArrayDeque(int numElements) {
    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的初始化容量必须是2^n
 你传的初始化容量如果是10
 那么实际申请的数组容量是16
 如果申请的容量是33,那么实际的容量是62
 如果申请的容量是62,那么实际申请的容量是128。
我们可以从allocateElements方法中看出以上的运行原理

ArrayDeque中add方法

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

public void addLast(E e) {
    if (e == null)
        throw new NullPointerException();
    //tail中保存的是即将加入末尾的元素的索引
    elements[tail] = e;
    //tail向后移动一位
    if ( (tail = (tail + 1) & (elements.length - 1)) == head)
        //tail和head相遇,空间用尽,需要扩容
        doubleCapacity();
}

注意事项:
   tail的计算公式(tail = (tail + 1) & (elements.length - 1))
   当tail到达容量最后一个的时候,tail就为等于0,否则tail的值tail+1

ArrayDeque扩容机制

private void doubleCapacity() {
    assert head == tail; //扩容时头部索引和尾部索引肯定相等
    int p = head;
    int n = elements.length;
    //头部索引到数组末端(length-1处)共有多少元素
    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 = a;
    //重置头尾索引
    head = 0;
    tail = n;
}
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaCourse/202207/3939.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者