Eine sehr einfache und schnelle Frage zu Java-Bibliotheken: Gibt es eine vorgefertigte Klasse, die eine Queue
mit einer festen maximalen Größe implementiert - dh sie ermöglicht immer das Hinzufügen von Elementen, entfernt jedoch stillschweigend Kopfelemente, um Platz für neu hinzugefügte Elemente zu schaffen.
Natürlich ist es trivial, es manuell zu implementieren:
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;
}
}
Soweit ich sehe, gibt es keine Standardimplementierung in Java stdlibs, aber vielleicht gibt es eine in Apache Commons oder so?
collections
queue
java
GreyCat
quelle
quelle
Antworten:
Apache Commons Collections 4 verfügt über eine CircularFifoQueue <> der Sie suchen. Javadoc zitieren:
Wenn Sie eine ältere Version der Apache Commons-Sammlungen (3.x) verwenden, können Sie den CircularFifoBuffer verwenden, der ohne Generika im Grunde dasselbe ist.
Update : Aktualisierte Antwort nach Veröffentlichung von Commons Collections Version 4, die Generika unterstützt.
quelle
EvictingQueue
zu Google Guava Version 15 um 2013-10.Guava hat jetzt eine EvictingQueue , eine nicht blockierende Warteschlange, die automatisch Elemente aus dem Kopf der Warteschlange entfernt, wenn versucht wird, neue Elemente zur Warteschlange hinzuzufügen, und diese ist voll.
quelle
EvictingQueue
ist ein FIFO. VersuchenQueue<Integer> fifo = EvictingQueue.create(2); fifo.add(1); fifo.add(2); fifo.add(3); System.out.println(fifo);
Sie im Zweifelsfall dieses Programm: Beachten Sie das Ergebnis:[2, 3]
Ich mag die @ FractalizeR-Lösung. Aber ich würde zusätzlich den Wert von super.add (o) behalten und zurückgeben!
quelle
LinkedList
Thread nicht sicher ist, wäre auch nicht sinnlos. Im Zusammenhang mit dieser Frage ist es aufgrund der spezifischen Anforderungen von OP besonders wichtig, dass das Hinzufügen eines Elements als atomare Operation ausgeführt wird. Mit anderen Worten, das Risiko, die Atomizität nicht sicherzustellen, wäre größer als bei einer regulären LinkedList.add(int,E)
stattdessen jemand anruft . Und ob esaddAll
wie beabsichtigt funktioniert, hängt von nicht spezifizierten Implementierungsdetails ab. Deshalb sollten Sie die Delegation der Vererbung vorziehen…Verwenden Sie Komposition nicht erweitert (ja, ich meine erweitert, wie in einem Verweis auf das Schlüsselwort erweitert in Java und ja, dies ist Vererbung). Die Komposition ist besser, da sie Ihre Implementierung vollständig abschirmt und es Ihnen ermöglicht, die Implementierung zu ändern, ohne die Benutzer Ihrer Klasse zu beeinträchtigen.
Ich empfehle, so etwas zu versuchen (ich tippe direkt in dieses Fenster, damit der Käufer auf Syntaxfehler achtet):
Eine bessere Option (basierend auf der Antwort von Asaf) könnte darin bestehen, den Apache Collections CircularFifoBuffer mit einer generischen Klasse zu versehen. Beispielsweise:
quelle
LinkedList
es implementiert wird. Das zusätzliche Objekt, das als Wrapper um die Liste erstellt wird, ist selbst bei "zig Millionen" Instanzen ziemlich klein.Das einzige, was ich weiß, das nur über begrenzten Speicherplatz verfügt, ist die BlockingQueue-Schnittstelle (die z. B. von der ArrayBlockingQueue-Klasse implementiert wird). Sie entfernen jedoch nicht das erste Element, wenn es gefüllt ist, sondern blockieren die Put-Operation, bis Speicherplatz frei ist (von einem anderen Thread entfernt) ).
Meines Wissens ist Ihre triviale Implementierung der einfachste Weg, um ein solches Verhalten zu erreichen.
quelle
BlockingQueue
keine Antwort. Ich habe an andere gängige Bibliotheken gedacht, wie Apache Commons, Eclipse-Bibliotheken, Spring-, Google-Ergänzungen usw.?Sie können eine MinMaxPriorityQueue von Google Guava aus dem Javadoc verwenden:
quelle
Map
wie ein benehmenList
. Beide Ideen zeigen jedoch ein völliges Unverständnis der Algorithmen und des Software-Designs.MinMaxPriorityQueue
in das, was das OP will, ist trivialer als das Ändern von aLinkedList
(der Code des OP kommt nicht einmal nahe).long
mich in meinem eigenen Vorschlag auf die Wahl eines absteigenden Typs als Cursortyp und sagte, dass er in der Praxis ausreichend breit sein würde, obwohl theoretisch mehr als 2 ^ 64 Objekte zu dieser Warteschlange hinzugefügt werden könnten, an welchem Punkt die Lösung zusammenbrechen würde .Eine LRUMap ist eine weitere Möglichkeit, auch von Apache Commons.
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/LRUMap.html
quelle
quelle