public E getFirst() { @SuppressWarnings("unchecked") E result = (E) elements[head]; if (result == null) throw new NoSuchElementException(); return result; }
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; }
题目: (tail = (tail + 1) & (elements.length - 1)) 这个那边见过,是不是在LongAdder里线程probe找cell 谁人逻辑? 这句话现实上就是对element.length 取余
可以看到,随着出队入队不绝使用,如果 tail 移动到 length-1 之后数组的第一个位置 0 处没有元素则须要将 tail 指向 0,依次循环,当 tail 如果便是 head 时分析数组要满了,接下来须要举行数组扩容,以是就有了上面 addLast(E e) 内里谁人 if 判定的逻辑去触发 doubleCapacity()。因此这也就表明了为什么 ArrayDeque 的初始容量必须是 2 的幂次(扩容每次都是成倍的,以是天然也满意 2 的幂次),由于只有容量为 2 的幂次时 ((tail + 1) & (elements.length - 1)) 使用中的 (elements.length - 1) 二进制最高位永世为 0,当 (tail + 1) 与其按位与使用时才华包管循环归零置位。ArrayDeque 的 doubleCapacity() 扩容使用的实现,如下:
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; }