Очень простой и быстрый вопрос о библиотеках Java: есть ли готовый класс, который реализует Queue
с фиксированным максимальным размером - то есть он всегда позволяет добавлять элементы, но он будет молча удалять элементы заголовка, чтобы освободить место для вновь добавленных элементов.
Конечно, реализовать это вручную тривиально:
import java.util.LinkedList;
public class LimitedQueue<E> extends LinkedList<E> {
private int limit;
public LimitedQueue(int limit) {
this.limit = limit;
}
@Override
public boolean add(E o) {
super.add(o);
while (size() > limit) { super.remove(); }
return true;
}
}
Насколько я вижу, в Java stdlibs нет стандартной реализации, но может быть, есть такая в Apache Commons или что-то в этом роде?
collections
queue
java
GreyCat
источник
источник
Ответы:
Apache commons collection 4 имеет CircularFifoQueue <>, который вы ищете. Цитируя Javadoc:
Если вы используете более старую версию коллекций Apache Commons (3.x), вы можете использовать CircularFifoBuffer, который в основном то же самое без дженериков.
Обновление : обновленный ответ после выпуска 4-й коллекции общих фондов, которая поддерживает дженерики.
источник
EvictingQueue
добавленную в Google Guava версии 15 около 2013-10.У Guava теперь есть EvictingQueue , неблокирующая очередь, которая автоматически выталкивает элементы из головы очереди при попытке добавить новые элементы в очередь, и она заполнена.
источник
EvictingQueue
. Если есть какие-либо сомнения, попробуйте эту программу:Queue<Integer> fifo = EvictingQueue.create(2); fifo.add(1); fifo.add(2); fifo.add(3); System.out.println(fifo);
Обратите внимание на результат:[2, 3]
Мне нравится решение @FractalizeR. Но я бы дополнительно сохранил и вернул значение из super.add (o)!
источник
LinkedList
это не потокобезопасно, также не будет бессмысленным. в контексте этого вопроса особое требование OP делает особенно важным, чтобы добавление элемента выполнялось как элементарная операция. другими словами, риск не обеспечения атомарности был бы больше, чем в случае обычного LinkedList.add(int,E)
. ИaddAll
работает ли как задумано, зависит от неуказанных деталей реализации. Вот почему вы должны отдавать предпочтение делегированию, а не наследованию…Использовать композицию не расширяет (да, я имею в виду расширяет, как в ссылке на ключевое слово extends в Java, и да, это наследование). Композиция выше, потому что она полностью защищает вашу реализацию, позволяя вам изменять реализацию, не влияя на пользователей вашего класса.
Я рекомендую попробовать что-то вроде этого (я печатаю прямо в этом окне, поэтому покупатель остерегается синтаксических ошибок):
Лучшим вариантом (основанным на ответе Асафа) может быть обертывание коллекций Apache CircularFifoBuffer с универсальным классом. Например:
источник
LinkedList
это реализовано. Дополнительный объект, созданный как обертка вокруг списка, будет довольно незначительным, даже с «десятками миллионов» экземпляров.Единственное, что я знаю, что имеет ограниченное пространство - это интерфейс BlockingQueue (который, например, реализуется классом ArrayBlockingQueue) - но они не удаляют первый элемент, если он заполнен, а вместо этого блокируют операцию put до тех пор, пока пространство не освободится (удаляется другим потоком ).
Насколько мне известно, ваша тривиальная реализация - самый простой способ получить такое поведение.
источник
BlockingQueue
это не ответ. Я думал о других распространенных библиотеках, таких как Apache Commons, библиотеки Eclipse, Spring, Google и т.д.?Вы можете использовать MinMaxPriorityQueue из Google Guava , из javadoc:
источник
Map
себя вести себя какList
. Но обе идеи показывают полное непонимание алгоритмов и дизайна программного обеспечения.MinMaxPriorityQueue
в то, что хочет ОП, более тривиально, чем изменениеLinkedList
(код ОП даже близко не подходит).long
в качестве типа курсора в моем собственном предложении, говоря, что на практике он будет достаточно широким, хотя теоретически вы можете добавить более 2 ^ 64 объектов в эту очередь, и в этот момент решение будет нарушено. ,LRUMap - это еще одна возможность, также от Apache Commons.
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/LRUMap.html
источник
источник