Bardzo proste i szybkie pytanie o biblioteki Java: czy istnieje gotowa klasa, która implementuje a Queue
o ustalonym maksymalnym rozmiarze - tzn. Zawsze pozwala na dodawanie elementów, ale po cichu usunie elementy główne, aby pomieścić miejsce dla nowo dodanych elementów.
Oczywiście wdrożenie go ręcznie jest trywialne:
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;
}
}
O ile mi wiadomo, nie ma standardowej implementacji w stdlibs Java, ale może jest taka w Apache Commons czy coś takiego?
collections
queue
java
GreyCat
źródło
źródło
Odpowiedzi:
Kolekcje Apache commons 4 mają CircularFifoQueue <>, czego szukasz. Cytując javadoc:
Jeśli używasz starszej wersji wspólnych kolekcji Apache (3.x), możesz użyć CircularFifoBuffer, który jest zasadniczo taki sam bez generycznych.
Aktualizacja : zaktualizowano odpowiedź po wydaniu wspólnej kolekcji w wersji 4, która obsługuje generyczne.
źródło
EvictingQueue
do Google Guava w wersji 15 około 2013-10.Guava ma teraz EvictingQueue , kolejkę nieblokującą, która automatycznie eksmituje elementy z głowy kolejki podczas próby dodania nowych elementów do kolejki i jest pełna.
źródło
EvictingQueue
to FIFO. W razie wątpliwości wypróbuj ten program:Queue<Integer> fifo = EvictingQueue.create(2); fifo.add(1); fifo.add(2); fifo.add(3); System.out.println(fifo);
Obserwuj wynik:[2, 3]
Lubię rozwiązanie @FractalizeR. Ale dodatkowo zatrzymałbym i zwrócił wartość z super.add (o)!
źródło
LinkedList
nie jest bezpieczne wątek, również nie byłoby sensu. w kontekście tego pytania szczególne wymaganie OP sprawia, że szczególnie ważne jest, aby dodanie elementu odbywało się jako operacja atomowa. innymi słowy, ryzyko braku zapewnienia atomowości byłoby większe niż w przypadku zwykłej LinkedList.add(int,E)
. To, czyaddAll
działa zgodnie z przeznaczeniem, zależy od nieokreślonych szczegółów implementacji. Właśnie dlatego powinieneś preferować przekazanieUżyj kompozycji nie rozszerza (tak mam na myśli rozszerzenie, ponieważ w odniesieniu do słowa kluczowego extends w Javie i tak jest to dziedziczenie). Kompozycja jest lepsza, ponieważ całkowicie chroni twoją implementację, pozwalając ci na zmianę implementacji bez wpływu na użytkowników twojej klasy.
Polecam wypróbowanie czegoś takiego (piszę bezpośrednio w tym oknie, więc kupujący uważaj na błędy składniowe):
Lepszą opcją (na podstawie odpowiedzi Asafa) może być owinięcie CircularFifoBuffer kolekcji Apache klasą ogólną. Na przykład:
źródło
LinkedList
to, jak to jest realizowane. Dodatkowy obiekt utworzony jako opakowanie wokół listy będzie dość niewielki, nawet przy „dziesiątkach milionów” instancji.Jedyne, co wiem, że ma ograniczoną przestrzeń to interfejs BlockingQueue (który jest np. Zaimplementowany przez klasę ArrayBlockingQueue) - ale nie usuwają pierwszego elementu, jeśli są wypełnione, ale zamiast tego blokują operację put, dopóki przestrzeń nie będzie wolna (usuwana przez inny wątek ).
Według mojej wiedzy trywialna implementacja jest najprostszym sposobem na uzyskanie takiego zachowania.
źródło
BlockingQueue
nie jest to odpowiedź. Myślałem o innych popularnych bibliotekach, takich jak Apache Commons, biblioteki Eclipse, Spring, dodatki Google itp.?Możesz użyć MinMaxPriorityQueue z Google Guava , z javadoc:
źródło
Map
zachowywać się jakList
. Ale oba pomysły pokazują całkowite niezrozumienie algorytmów i projektowania oprogramowania.MinMaxPriorityQueue
w to, czego chce OP, jest bardziej trywialne niż modyfikowanie aLinkedList
(kod OP nawet się nie zbliża).long
jako typu kursora w ramach mojej własnej sugestii, mówiąc, że będzie on wystarczająco szeroki w praktyce, nawet jeśli teoretycznie można dodać więcej niż 2 ^ 64 obiektów do tej kolejki, w którym to momencie rozwiązanie się załamie .LRUMap to kolejna możliwość, również z Apache Commons.
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/LRUMap.html
źródło
źródło