Реализация очереди фиксированного размера в Java: автоочистка
Быстрый ответ
LinkedBlockingDeque
станет идеальной реализацией для построения такой очереди с пределом по вместимости. Установив максимальный размер, вы будете иметь очередь, которая сама избавляется от самых старых элементов при превышении указанного лимита. Вот как это сделать:
// Задаем предел размера очереди
int capacity = 10;
// Создаем очередь с ограниченным размером
LinkedBlockingDeque<Integer> queue = new LinkedBlockingDeque<>(capacity);
// Добавляем новый элемент
queue.addLast(element);
// Управляем размером очереди
if (queue.size() > capacity) {
queue.removeFirst();
}
Так, очередь всегда будет сохранять установленный размер, удаляя при этом старые элементы.
Реализация фиксированного размера очереди с помощью LinkedHashMap
LinkedHashMap
в Java — это мощный инструмент, который можно сконфигурировать для создания очереди с фиксированным размером. Для автоматического удаления старых элементов достаточно настроить метод removeEldestEntry
.
// Устанавливаем размер вместимости
int capacity = 10;
// Используем LinkedHashMap для создания очереди
LinkedHashMap<Integer, Boolean> map = new LinkedHashMap<Integer, Boolean>(capacity, 0.75F, true) {
protected boolean removeEldestEntry(Map.Entry<Integer, Boolean> eldest) {
// Если размер превышает вместимость, удаляем старый элемент
return size() > capacity;
}
};
Библиотеки на помощь: Guava и Apache Commons
Не нужно изобретать велосипед: EvictingQueue
из библиотеки Google Guava и CircularFifoQueue
от Apache Commons — прекрасны для создания очередей с автоматическим удалением устаревших элементов.
// Стандартная очередь от Guava
EvictingQueue<Integer> evictingQueue = EvictingQueue.create(capacity);
// Циклическая очередь от Apache
CircularFifoQueue<Integer> fifoQueue = new CircularFifoQueue<>(capacity);
Заметьте: оба типа данных не поддерживают null
-значения.
Простая реализация с помощью ArrayDeque
Если вам нужна простота, выберите ArrayDeque
. Его нужно только немного адаптировать, добавив методы для контроля за размером очереди:
ArrayDeque<Integer> deque = new ArrayDeque<>(capacity);
// Переопределите метод добавления для контроля размера
public boolean add(Integer e) {
if (deque.size() == capacity) {
deque.pollFirst();
}
return deque.offerLast(e);
}
Рекомендации по выбору реализации
При выборе реализации необходимо ориентироваться на требования к потокобезопасности, производительности и поддержке null
-значений:
LinkedBlockingDeque
: Потокобезопасна, но может уступать по скорости из-за необходимости синхронизации.- Настройка
LinkedHashMap
: Требует некоторого усилия для наследования и переопределения методов. - Библиотеки сторонних разработчиков: Простота добавления зависимости и использования готового решения.
- Модификация
ArrayDeque
: Быстра и лаконична, но подходит только для не потокобезопасных задач.
Создаем собственную очередь путем наследования от AbstractQueue
Если вам нужен полный контроль над функционалом, вы можете наследовать AbstractQueue
и создать свою собственную очередь с фиксированным размером:
public class FixedSizeQueue<E> extends AbstractQueue<E> {
// Настраивайте по своему усмотрению.
}