Храните индекс самого старого элемента и текущий размер. Новый элемент пишется в (head + size) % capacity; при полном буфере перезаписывается head и сдвигается начало.
Создание кольцевого буфера с перезаписью по принципу FIFO
Храните индекс самого старого элемента и текущий размер. Новый элемент пишется в (head + size) % capacity; при полном буфере перезаписывается head и сдвигается начало.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо разработать структуру данных — кольцевой буфер фиксированного объёма, работающий по принципу FIFO (First In, First Out). Основные свойства:
- Имеет заранее заданную ёмкость, которую нельзя изменить после создания;
- При достижении полной загрузки новые элементы заменяют самые старые, сохраняя порядок очереди.
Ответ
Храните индекс самого старого элемента и текущий размер. Новый элемент пишется в (head + size) % capacity; при полном буфере перезаписывается head и сдвигается начало.
final class RingBuffer<T> {
private final Object[] data;
private int head, size;
RingBuffer(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
data = new Object[capacity];
}
void add(T value) {
java.util.Objects.requireNonNull(value);
int index = (int) (((long) head + size) % data.length);
data[index] = value;
if (size == data.length) head = (head + 1) % data.length;
else size++;
}
@SuppressWarnings("unchecked")
T poll() {
if (size == 0) return null;
T value = (T) data[head];
data[head] = null;
head = (head + 1) % data.length;
size--;
return value;
}
}
Операции O(1), память O(capacity). Null запрещён, чтобы отличать пустоту при poll. Это однопоточная реализация; конкурентные операции требуют общей синхронизации.