В языке Java и среде выполнения нет существующей реализации. Все очереди расширяют AbstractQueue , и в его документе четко указано, что добавление элемента в полную очередь всегда заканчивается исключением. Было бы лучше (и довольно просто) обернуть Queue в собственный класс для обеспечения необходимой вам функциональности.
Еще раз, поскольку все очереди являются дочерними по отношению к AbstractQueue, просто используйте это как свой внутренний тип данных, и у вас должна быть гибкая реализация, работающая практически в кратчайшие сроки :-)
ОБНОВИТЬ:
Как указано ниже, доступны две открытые реализации (этот ответ довольно старый, ребята!), Подробности см. В этом ответе .
@ user7294900 Спасибо, ссылка исправлена. К вашему сведению, Stack Overflow предлагает вам внести такие изменения непосредственно в ответ самостоятельно. Редактировать может кто угодно, а не только оригинальный автор. В этом отношении Stack Overflow больше похож на Википедию.
Basil Bourque
@BasilBourque да, но такие правки могут быть отклонены даже мной, при смене ссылок это серая зона
user7294900
18
Я только что реализовал очередь фиксированного размера таким образом:
publicclassLimitedSizeQueue<K>extendsArrayList<K>{privateint maxSize;publicLimitedSizeQueue(int size){this.maxSize = size;}publicboolean add(K k){boolean r =super.add(k);if(size()> maxSize){
removeRange(0, size()- maxSize);}return r;}public K getYoungest(){return get(size()-1);}public K getOldest(){return get(0);}}
Я согласен с Амхедом выше. Удалите - 1. В противном случае при максимальной емкости вы получите массив с maxSize + 1, поскольку мы говорим о 0. Например. Если maxSize = 50, то при добавлении нового объекта формула removeRange в исходном сообщении будет 51 - 50 - 1 = 0 (т.е. ничего не удалено).
Etep 06
8
Это то, что я сделал с Queueупаковкой. LinkedListЭто фиксированный размер, который я указываю здесь - 2;
publicstaticQueue<String> pageQueue;
pageQueue =newLinkedList<String>(){privatestaticfinallong serialVersionUID =-6707803882461262867L;publicboolean add(String object){boolean result;if(this.size()<2)
result =super.add(object);else{super.removeFirst();
result =super.add(object);}return result;}};....TMarket.pageQueue.add("ScreenOne");....TMarket.pageQueue.add("ScreenTwo");.....
Этот класс выполняет свою работу, используя композицию вместо наследования (другие ответы здесь), что устраняет возможность определенных побочных эффектов (как описано Джошем Блохом в Essential Java). Обрезка нижележащего LinkedList происходит в методах add, addAll и offer.
Не совсем понятно, какие у вас требования, которые заставили вас задать этот вопрос. Если вам нужна структура данных фиксированного размера, вы можете также изучить другие политики кэширования. Однако, поскольку у вас есть очередь, я предполагаю, что вы ищете какой-то тип функциональности маршрутизатора. В этом случае я бы выбрал кольцевой буфер: массив с первым и последним индексами. Всякий раз, когда добавляется элемент, вы просто увеличиваете индекс последнего элемента, а когда элемент удаляется, увеличиваете индекс первого элемента. В обоих случаях сложение выполняется по модулю размера массива, и обязательно увеличивайте другой индекс, когда это необходимо, то есть когда очередь заполнена или пуста.
Кроме того, если это приложение типа маршрутизатора, вы также можете поэкспериментировать с таким алгоритмом, как Random Early Dropping (RED), который случайным образом удаляет элементы из очереди еще до того, как она будет заполнена. В некоторых случаях было обнаружено, что RED имеет лучшую общую производительность, чем простой метод, позволяющий очереди заполняться перед отбрасыванием.
На самом деле вы можете написать свой собственный impl на основе LinkedList, это довольно просто, просто переопределите метод добавления и выполните команду.
Ответы:
В языке Java и среде выполнения нет существующей реализации. Все очереди расширяют AbstractQueue , и в его документе четко указано, что добавление элемента в полную очередь всегда заканчивается исключением. Было бы лучше (и довольно просто) обернуть Queue в собственный класс для обеспечения необходимой вам функциональности.
Еще раз, поскольку все очереди являются дочерними по отношению к AbstractQueue, просто используйте это как свой внутренний тип данных, и у вас должна быть гибкая реализация, работающая практически в кратчайшие сроки :-)
ОБНОВИТЬ:
Как указано ниже, доступны две открытые реализации (этот ответ довольно старый, ребята!), Подробности см. В этом ответе .
источник
collection.deque
с указаннымmaxlen
.На самом деле LinkedHashMap делает именно то, что вы хотите. Вам нужно переопределить
removeEldestEntry
метод.Пример очереди с максимум 10 элементами:
Если removeEldestEntry возвращает true, самая старая запись удаляется с карты.
источник
Да, два
Из моего собственного повторяющегося вопроса с этим правильным ответом я узнал о двух:
EvictingQueue
в Google GuavaCircularFifoQueue
в Apache CommonsЯ продуктивно пользовался Гуавой
EvictingQueue
, работал хорошо.Чтобы создать экземпляр
EvictingQueue
вызова статического фабричного методаcreate
и указать свой максимальный размер.источник
CircularFifoQueue
ссылка мертва, используйте вместо нее commons.apache.org/proper/commons-collections/apidocs/org/…Я только что реализовал очередь фиксированного размера таким образом:
источник
removeRange(0, size() - maxSize)
Это то, что я сделал с
Queue
упаковкой.LinkedList
Это фиксированный размер, который я указываю здесь - 2;источник
Я думаю, что вы описываете круговую очередь. Вот пример , и вот лучше один
источник
Этот класс выполняет свою работу, используя композицию вместо наследования (другие ответы здесь), что устраняет возможность определенных побочных эффектов (как описано Джошем Блохом в Essential Java). Обрезка нижележащего LinkedList происходит в методах add, addAll и offer.
источник
Использование и результат тестирования:
источник
Звучит как обычный список, в котором метод добавления содержит дополнительный фрагмент, который обрезает список, если он становится слишком длинным.
Если это слишком просто, вам, вероятно, нужно отредактировать описание проблемы.
источник
Также см. Этот вопрос SO или ArrayBlockingQueue (будьте осторожны с блокировкой, это может быть нежелательным в вашем случае).
источник
Не совсем понятно, какие у вас требования, которые заставили вас задать этот вопрос. Если вам нужна структура данных фиксированного размера, вы можете также изучить другие политики кэширования. Однако, поскольку у вас есть очередь, я предполагаю, что вы ищете какой-то тип функциональности маршрутизатора. В этом случае я бы выбрал кольцевой буфер: массив с первым и последним индексами. Всякий раз, когда добавляется элемент, вы просто увеличиваете индекс последнего элемента, а когда элемент удаляется, увеличиваете индекс первого элемента. В обоих случаях сложение выполняется по модулю размера массива, и обязательно увеличивайте другой индекс, когда это необходимо, то есть когда очередь заполнена или пуста.
Кроме того, если это приложение типа маршрутизатора, вы также можете поэкспериментировать с таким алгоритмом, как Random Early Dropping (RED), который случайным образом удаляет элементы из очереди еще до того, как она будет заполнена. В некоторых случаях было обнаружено, что RED имеет лучшую общую производительность, чем простой метод, позволяющий очереди заполняться перед отбрасыванием.
источник
На самом деле вы можете написать свой собственный impl на основе LinkedList, это довольно просто, просто переопределите метод добавления и выполните команду.
источник
Я думаю, что лучший подходящий ответ - это другой вопрос .
В коллекциях Apache Commons 4 есть CircularFifoQueue, которую вы ищете. Цитата из javadoc:
источник
Простое решение, ниже - очередь "String"
Обратите внимание, что это не будет поддерживать порядок элементов в очереди, но заменит самую старую запись.
источник
Как сказано в ООП, мы должны предпочесть композицию наследованию.
Вот мое решение с учетом этого.
источник