## jdk源码分析ArrayDeque

2016-10-27 19:53  v_ZSW  阅读(494)  评论(0编辑  收藏  举报

# ArrayDeque

## 一、容量

### 1.2指定初始化容容量

    public ArrayDeque(int numElements) {
allocateElements(numElements);
}
private void allocateElements(int numElements) {
int initialCapacity = MIN_INITIAL_CAPACITY;
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];
}


### 1.4扩展容量

    private void doubleCapacity() {
int n = elements.length;
int r = n - p; // number of elements to the right of p
int newCapacity = n << 1;//bit count faster
if (newCapacity < 0)
throw new IllegalStateException("Sorry, deque too big");
Object[] a = new Object[newCapacity];
System.arraycopy(elements, 0, a, r, p);//copy the left of the tail(exclude tail)
elements = a;
tail = n;
}


### 1.5细说doubleCapacity

1.求两本容量，n<<1，使用位运算要快于四则运算，因为这更贴近运算器电路的设计
2.复制原来的数组到目标数组要注意顺序！

## 二、头尾指针

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


    public void addFirst(E e) {
if (e == null)
throw new NullPointerException();
doubleCapacity();
}


## 五、利用空间局部性

    public boolean removeFirstOccurrence(Object o) {
if (o == null)
return false;
int mask = elements.length - 1;
Object x;
while ( (x = elements[i]) != null) {
if (o.equals(x)) {
delete(i);
return true;
}
i = (i + 1) & mask;
}
return false;
}


## 6.优化删除策略

    private boolean delete(int i) {
checkInvariants();
final Object[] elements = this.elements;
final int mask = elements.length - 1;
final int t = tail;
final int front = (i - h) & mask;
final int back  = (t - i) & mask;

// Invariant: head <= i < tail mod circularity if (front >= ((t - h) & mask))
throw new ConcurrentModificationException();

// Optimize for least element motion
//最优化删除策略
if (front < back) {//如果要删除的元素在前半段
System.arraycopy(elements, h, elements, h + 1, front);//将要删除元素的前继元素往后移动一格
} else { // Wrap around
System.arraycopy(elements, 0, elements, 1, i);//把i前面的元素往后挪一格
}
elements[h] = null;//帮助垃圾收集
return false;
} else {
if (i < t) { // Copy the null tail as well
System.arraycopy(elements, i + 1, elements, i, back);
tail = t - 1;
} else { // Wrap around
System.arraycopy(elements, i + 1, elements, i, mask - i);
System.arraycopy(elements, 1, elements, 0, t);
tail = (t - 1) & mask;
}
return true;
}
}