Nie ma istniejącej implementacji w języku Java i środowisku wykonawczym. Wszystkie kolejki rozszerzają AbstractQueue , a jego dokument jasno stwierdza, że dodanie elementu do pełnej kolejki zawsze kończy się wyjątkiem. Najlepszym rozwiązaniem (i całkiem prostym) byłoby umieszczenie kolejki we własnej klasie, aby mieć potrzebną funkcjonalność.
Ponownie, ponieważ wszystkie kolejki są dziećmi AbstractQueue, po prostu użyj tego jako wewnętrznego typu danych i powinieneś mieć elastyczną implementację działającą praktycznie w mgnieniu oka :-)
AKTUALIZACJA:
Jak opisano poniżej, dostępne są dwie otwarte implementacje (ludzie, ta odpowiedź jest dość stara!) . Szczegółowe informacje można znaleźć w tej odpowiedzi .
@ user7294900 Dzięki, link poprawiony. Do Twojej wiadomości, Stack Overflow zaprasza Cię do samodzielnego wprowadzania takich zmian bezpośrednio w odpowiedzi. Edytować może każdy, nie tylko oryginalny autor. Stack Overflow ma pod tym względem bardziej polubić Wikipedię.
Basil Bourque
@BasilBourque tak, ale takie zmiany mogą być odrzucone nawet przeze mnie przy zmianie linków to szara strefa
user7294900
18
Właśnie zaimplementowałem kolejkę o stałym rozmiarze w ten sposób:
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);}}
Zgadzam się z Amhed powyżej. Usuń - 1. W przeciwnym razie przy maksymalnej pojemności otrzymasz tablicę o maksymalnym rozmiarze + 1, ponieważ mówimy o opartej na 0. Na przykład. Jeśli maxSize = 50, to podczas dodawania nowego obiektu formuła removeRange w oryginalnym poście będzie miała wartość 51 - 50 - 1 = 0 (tj. Nic nie zostało usunięte).
Etep
8
To jest to, co zrobiłem z Queueopakowaniem LinkedList, ma stały rozmiar, który podam tutaj to 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");.....
Ta klasa spełnia swoje zadanie, wykorzystując kompozycję zamiast dziedziczenia (inne odpowiedzi tutaj), co eliminuje możliwość wystąpienia pewnych skutków ubocznych (opisanych przez Josha Blocha w Essential Java). Przycinanie podstawowej LinkedList odbywa się w metodach add, addAll i offer.
Nie jest do końca jasne, jakie masz wymagania, które skłoniły Cię do zadania tego pytania. Jeśli potrzebujesz struktury danych o stałym rozmiarze, możesz również przyjrzeć się różnym zasadom buforowania. Ponieważ jednak masz kolejkę, przypuszczam, że szukasz jakiejś funkcji routera. W takim przypadku wybrałbym bufor pierścieniowy: tablicę, która ma pierwszy i ostatni indeks. Za każdym razem, gdy dodawany jest element, po prostu zwiększasz indeks ostatniego elementu, a gdy element jest usuwany, zwiększasz indeks pierwszego elementu. W obu przypadkach dodawanie jest wykonywane modulo rozmiar tablicy i upewnij się, że w razie potrzeby zwiększasz inny indeks, to znaczy, gdy kolejka jest pełna lub pusta.
Ponadto, jeśli jest to aplikacja typu routera, możesz również poeksperymentować z algorytmem, takim jak Random Early Dropping (RED), który losowo usuwa elementy z kolejki, zanim zostanie ona zapełniona. W niektórych przypadkach RED ma lepszą ogólną wydajność niż prosta metoda pozwalająca na zapełnienie kolejki przed upuszczeniem.
Odpowiedzi:
Nie ma istniejącej implementacji w języku Java i środowisku wykonawczym. Wszystkie kolejki rozszerzają AbstractQueue , a jego dokument jasno stwierdza, że dodanie elementu do pełnej kolejki zawsze kończy się wyjątkiem. Najlepszym rozwiązaniem (i całkiem prostym) byłoby umieszczenie kolejki we własnej klasie, aby mieć potrzebną funkcjonalność.
Ponownie, ponieważ wszystkie kolejki są dziećmi AbstractQueue, po prostu użyj tego jako wewnętrznego typu danych i powinieneś mieć elastyczną implementację działającą praktycznie w mgnieniu oka :-)
AKTUALIZACJA:
Jak opisano poniżej, dostępne są dwie otwarte implementacje (ludzie, ta odpowiedź jest dość stara!) . Szczegółowe informacje można znaleźć w tej odpowiedzi .
źródło
collection.deque
z określonymmaxlen
.Właściwie LinkedHashMap robi dokładnie to, co chcesz. Musisz nadpisać
removeEldestEntry
metodę.Przykład kolejki z maksymalnie 10 elementami:
Jeśli „removeEldestEntry” zwróci wartość true, najstarszy wpis zostanie usunięty z mapy.
źródło
Tak, dwa
Z mojego zduplikowanego pytania z tą poprawną odpowiedzią dowiedziałem się o dwóch:
EvictingQueue
w Google GuavaCircularFifoQueue
w Apache CommonsRobiłem produktywny użytek z guawy
EvictingQueue
, pracowałem dobrze.Aby utworzyć wystąpienie
EvictingQueue
wywołania statycznej metody fabrykicreate
i określić maksymalny rozmiar.źródło
CircularFifoQueue
link jest martwy, użyj zamiast tego commons.apache.org/proper/commons-collections/apidocs/org/…Właśnie zaimplementowałem kolejkę o stałym rozmiarze w ten sposób:
źródło
removeRange(0, size() - maxSize)
To jest to, co zrobiłem z
Queue
opakowaniemLinkedList
, ma stały rozmiar, który podam tutaj to 2;źródło
Myślę, że to, co opisujesz, to cykliczna kolejka. Oto przykład i tutaj jest lepszy jeden
źródło
Ta klasa spełnia swoje zadanie, wykorzystując kompozycję zamiast dziedziczenia (inne odpowiedzi tutaj), co eliminuje możliwość wystąpienia pewnych skutków ubocznych (opisanych przez Josha Blocha w Essential Java). Przycinanie podstawowej LinkedList odbywa się w metodach add, addAll i offer.
źródło
Użytkowanie i wynik testu:
źródło
Brzmi jak zwykła lista, w której metoda add zawiera dodatkowy fragment kodu, który obcina listę, jeśli stanie się zbyt długa.
Jeśli jest to zbyt proste, prawdopodobnie konieczna będzie edycja opisu problemu.
źródło
Zobacz także to pytanie SO lub ArrayBlockingQueue (uważaj na blokowanie, może to być niepożądane w twoim przypadku).
źródło
Nie jest do końca jasne, jakie masz wymagania, które skłoniły Cię do zadania tego pytania. Jeśli potrzebujesz struktury danych o stałym rozmiarze, możesz również przyjrzeć się różnym zasadom buforowania. Ponieważ jednak masz kolejkę, przypuszczam, że szukasz jakiejś funkcji routera. W takim przypadku wybrałbym bufor pierścieniowy: tablicę, która ma pierwszy i ostatni indeks. Za każdym razem, gdy dodawany jest element, po prostu zwiększasz indeks ostatniego elementu, a gdy element jest usuwany, zwiększasz indeks pierwszego elementu. W obu przypadkach dodawanie jest wykonywane modulo rozmiar tablicy i upewnij się, że w razie potrzeby zwiększasz inny indeks, to znaczy, gdy kolejka jest pełna lub pusta.
Ponadto, jeśli jest to aplikacja typu routera, możesz również poeksperymentować z algorytmem, takim jak Random Early Dropping (RED), który losowo usuwa elementy z kolejki, zanim zostanie ona zapełniona. W niektórych przypadkach RED ma lepszą ogólną wydajność niż prosta metoda pozwalająca na zapełnienie kolejki przed upuszczeniem.
źródło
Właściwie możesz napisać swój własny plik Impl oparty na LinkedList, jest to całkiem proste, po prostu zastąp metodę add i wykonaj pięciolinię.
źródło
Myślę, że najbardziej pasująca odpowiedź pochodzi z tego innego pytania .
Apache commons collections 4 ma CircularFifoQueue, którego szukasz. Cytując javadoc:
źródło
Proste rozwiązanie, poniżej znajduje się kolejka „Ciąg”
Zauważ, że nie zachowa to kolejności elementów w kolejce, ale zastąpi najstarszy wpis.
źródło
Zgodnie z zaleceniami w programach OOP, powinniśmy preferować kompozycję zamiast dziedziczenia
Oto moje rozwiązanie, mając to na uwadze.
źródło