Наконец я нашел это !!!
Причина не только в производительности и операциях с битовой маской (да, они быстрее, но незначительно). Реальная причина в том, чтобы разрешить возврат назад elements
емкость, если мы используем последовательные операции добавления-удаления . Другими словами: повторно использовать освобожденные ячейки после операции remove()
.
Рассмотрим следующие примеры (начальная емкость 16 ):
Только add()
:
добавить 15 элементов => голова = 0, хвост = 15
добавить еще 5 элементов => doubleCapacity()
=> голова = 0, хвост = 20, емкость = 32
![enter image description here](https://i.stack.imgur.com/VXMVQ.png)
add()
remove()
add()
:
добавить 15 элементов => голова = 0, хвост = 15
удалить 10 элементов => хвост возвращается назад к удаленным индексам => голова = 10, хвост = 15
добавить еще 5 элементов => емкость остается 16, массив elements[]
не перестроен и не перераспределен! => новые элементы добавляются на место удаленных элементов в начало массива => head = 10, tail = 4 ( зацикливается назад до начала массива с 15-> 0-> 1-> 2-> 3-> 4). Обратите внимание, что значения 16-19 вставляются в индексы 0-3
![enter image description here](https://i.stack.imgur.com/BPF2v.png)
Таким образом, в этом случае использование степени двух и кратких битовых операций имеет гораздо больше смысла. При таком подходе операции типа if ( (tail = (tail + 1) & (elements.length - 1)) == head)
позволяют легко назначать и проверять, что петля tail
не перекрывается с head
(да, тупая змея, где на самом деле хвост кусает голову :) )
Фрагмент кода для игры:
ArrayDeque<String> q = new ArrayDeque<>(15); // capacity is 16
// add 15 elements
q.add("0"); q.add("1"); q.add("2"); q.add("3"); q.add("4");
q.add("5"); q.add("6"); q.add("7"); q.add("8"); q.add("9");
q.add("10"); q.add("11");q.add("12");q.add("13");q.add("14");
// remove 10 elements from the head => tail LOOPS BACK in the elements[]
q.poll();q.poll();q.poll();q.poll();q.poll();q.poll();q.poll();q.poll();q.poll();q.poll();
// add 5 elements => the elements[] is not reallocated!
q.add("15");q.add("16");q.add("17");q.add("18");q.add("19");
q.poll();