持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
删除数据
源码:
void removeAt(final int removeIndex) {
final Object[] items = this.items;
if (removeIndex == takeIndex) {
items[takeIndex] = null;
if (++takeIndex == items.length)
takeIndex = 0;
count--;
if (itrs != null)
itrs.elementDequeued();
} else {
final int putIndex = this.putIndex;
for (int i = removeIndex;;) {
int next = i + 1;
if (next == items.length)
next = 0;
if (next != putIndex) {
items[i] = items[next];
i = next;
} else {
items[i] = null;
this.putIndex = i;
break;
}
}
count--;
if (itrs != null)
itrs.removedAt(removeIndex);
}
notFull.signal();
}
if (removeIndex == takeIndex) { items[takeIndex] = null; if (++takeIndex == items.length) takeIndex = 0; count--; if (itrs != null) itrs.elementDequeued();
删除情况1:如果删除位置正好等于下次要拿数据的位置,则把下次要拿数据的位置置为空,然后把要拿数据的位置往后移动一位,将当前数组的大小减一。
final int putIndex = this.putIndex; ... int next = i + 1; if (next == items.length) next = 0; if (next != putIndex) { items[i] = items[next]; i = next; } else { items[i] = null; this.putIndex = i; break; ... }
删除情况2:找到要删除元素的下一个,如果下一个元素不等于 putIndex,则将下一个元素往前移动一位,如果下一个元素等于 putIndex,则直接删除元素,下次放元素时会从本次删除的元素位置放。
总结一下,删除元素主要分为两种情况: 1:删除位置和 takeIndex 的关系:删除位置和 takeIndex 一样,比如 takeIndex 是 3, 而要删除的位置正好也是 3,那么就把位置 3 的数据置为 null ,并重新计算 takeIndex 为 4。 2:找到要删除元素的下一个,计算删除元素和 putIndex 的关系 如果下一个元素不是 putIndex,就把下一个元素往前移动一位 如果下一个元素是 putIndex,把 putIndex 的值修改成删除的位置
总结
ArrayBlockingQueue 底层的数据结构是有界的数组,大体上和其它队列差别不多,只是ArrayBlockingQueue当 takeIndex、putIndex 到队尾的时候,都会重新从 0 开始循环,相当于是一个环,这是需要注意的点。