ArrayDeque

ArrayDeque实现了Deque接口,内部存储数据结构为可调整大小的数组,而且没有容量限制,线程非安全。

其继承关系如下:

Deque

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

void addFirst(E e);

void addLast(E e);

boolean offerFirst(E e);

boolean offerLast(E e);

E removeFirst();

E removeLast();

E pollFirst();

E pollLast();

E getFirst();

E getLast();

E peekFirst();

E peekLast();

boolean removeFirstOccurrence(Object o);

boolean removeLastOccurrence(Object o);

// *** Queue methods ***

boolean add(E e);

boolean offer(E e);

E remove();

E poll();

E element();

E peek();


// *** Stack methods ***
void push(E e);

E pop();


// *** Collection methods ***

boolean remove(Object o);

boolean contains(Object o);

public int size();

Iterator<E> iterator();

Iterator<E> descendingIterator();

主要属性

1
2
3
4
5
6
7
8
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable
{
transient Object[] elements;
transient int head;
transient int tail;
private static final int MIN_INITIAL_CAPACITY = 8;

构造器

1
2
3
4
5
6
7
8
9
10
public ArrayDeque() {
elements = new Object[16];
}
public ArrayDeque(int numElements) {
allocateElements(numElements);
}
public ArrayDeque(Collection<? extends E> c) {
allocateElements(c.size());
addAll(c);
}

入队

1
2
3
4
5
6
7
8
9
10
11
public boolean add(E e) {
addLast(e);
return true;
}
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
}

扩容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 = a;
head = 0;
tail = n;
}

出队

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public E remove() {
return removeFirst();
}

public E removeFirst() {
E x = pollFirst();
if (x == null)
throw new NoSuchElementException();
return x;
}
public E poll() {
return 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;
}

总结

  1. ArrayDeque采用数组实现双端队列
  2. 出队入队是通过头尾指针循环利用数组实现
  3. 容量不足时是会扩容的,每次扩容容量增加一倍
  4. 可以直接作为栈使用
坚持原创技术分享,您的支持将鼓励我继续创作!