Existe-t-il une file d'attente de taille fixe qui supprime les éléments excessifs?
127
J'ai besoin d'une file d'attente de taille fixe. Lorsque j'ajoute un élément et que la file d'attente est pleine, elle doit automatiquement supprimer l'élément le plus ancien.
Il n'existe aucune implémentation existante dans le langage Java et le Runtime. Toutes les files d'attente étendent AbstractQueue , et son document indique clairement que l'ajout d'un élément à une file d'attente complète se termine toujours par une exception. Il serait préférable (et assez simple) d'envelopper une file d'attente dans une classe à vous pour avoir les fonctionnalités dont vous avez besoin.
Encore une fois, comme toutes les files d'attente sont des enfants de AbstractQueue, utilisez simplement cela comme type de données interne et vous devriez avoir une implémentation flexible en un rien de temps :-)
METTRE À JOUR:
Comme indiqué ci-dessous, il existe deux implémentations ouvertes disponibles (cette réponse est assez ancienne, les amis!), Voir cette réponse pour plus de détails.
@ user7294900 Merci, lien corrigé. Pour info, Stack Overflow vous invite à apporter vous-même de telles modifications directement à une réponse. Tout le monde peut modifier, pas seulement l'auteur original. Stack Overflow est destiné à ressembler davantage à Wikipedia à cet égard.
Basil Bourque
@BasilBourque oui, mais de telles modifications peuvent être rejetées même par moi lorsque je change de lien, c'est une zone grise
user7294900
18
Je viens d'implémenter une file d'attente de taille fixe de cette façon:
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);}}
Je suis d'accord avec Amhed ci-dessus. Supprimez le - 1. Sinon, à la capacité maximale, vous vous retrouverez avec un tableau qui est maxSize + 1 puisque nous parlons de 0 basé. Par exemple. Si maxSize = 50, lors de l'ajout d'un nouvel objet, la formule removeRange dans le message d'origine sera 51 - 50 - 1 = 0 (c'est-à-dire rien de supprimé).
Etep
8
C'est ce que j'ai fait avec Queueenveloppé avec LinkedList, il est de taille fixe que je donne ici est 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");.....
Cette classe fait le travail en utilisant la composition au lieu de l'héritage (autres réponses ici), ce qui supprime la possibilité de certains effets secondaires (comme couvert par Josh Bloch dans Essential Java). Le rognage de la LinkedList sous-jacente se produit sur les méthodes add, addAll et offer.
En fait, il aurait besoin de supprimer le premier élément (c'est-à-dire le plus ancien), la troncature supprimerait le dernier élément. Toujours pratique avec une LinkedList.
Les exigences que vous avez qui vous ont amené à poser cette question ne sont pas très claires. Si vous avez besoin d'une structure de données de taille fixe, vous pouvez également envisager différentes stratégies de mise en cache. Cependant, comme vous avez une file d'attente, ma meilleure supposition est que vous recherchez un type de fonctionnalité de routeur. Dans ce cas, j'irais avec un tampon en anneau: un tableau qui a un premier et un dernier index. Chaque fois qu'un élément est ajouté, vous incrémentez simplement le dernier index d'élément, et lorsqu'un élément est supprimé, incrémentez le premier index d'élément. Dans les deux cas, l'ajout est effectué en fonction de la taille du tableau, et veillez à incrémenter l'autre index si nécessaire, c'est-à-dire lorsque la file d'attente est pleine ou vide.
De plus, s'il s'agit d'une application de type routeur, vous pouvez également essayer un algorithme tel que Random Early Dropping (RED), qui supprime des éléments de la file d'attente de manière aléatoire avant même qu'elle ne se remplisse. Dans certains cas, RED s'est avéré avoir de meilleures performances globales que la méthode simple permettant à la file d'attente de se remplir avant de tomber.
Réponses:
Il n'existe aucune implémentation existante dans le langage Java et le Runtime. Toutes les files d'attente étendent AbstractQueue , et son document indique clairement que l'ajout d'un élément à une file d'attente complète se termine toujours par une exception. Il serait préférable (et assez simple) d'envelopper une file d'attente dans une classe à vous pour avoir les fonctionnalités dont vous avez besoin.
Encore une fois, comme toutes les files d'attente sont des enfants de AbstractQueue, utilisez simplement cela comme type de données interne et vous devriez avoir une implémentation flexible en un rien de temps :-)
METTRE À JOUR:
Comme indiqué ci-dessous, il existe deux implémentations ouvertes disponibles (cette réponse est assez ancienne, les amis!), Voir cette réponse pour plus de détails.
la source
collection.deque
avec unmaxlen
.En fait, LinkedHashMap fait exactement ce que vous voulez. Vous devez remplacer la
removeEldestEntry
méthode.Exemple pour une file d'attente de 10 éléments maximum:
Si "removeEldestEntry" renvoie true, l'entrée la plus ancienne est supprimée de la carte.
la source
Oui, deux
De ma propre question en double avec cette réponse correcte , j'ai appris deux:
EvictingQueue
dans Google GuavaCircularFifoQueue
dans Apache CommonsJ'ai fait un usage productif de la goyave
EvictingQueue
, j'ai bien travaillé.Pour instancier un
EvictingQueue
appel, la méthode de fabrique statiquecreate
et spécifiez votre taille maximale.la source
CircularFifoQueue
lien est mort, utilisez plutôt commons.apache.org/proper/commons-collections/apidocs/org/...Je viens d'implémenter une file d'attente de taille fixe de cette façon:
la source
removeRange(0, size() - maxSize)
C'est ce que j'ai fait avec
Queue
enveloppé avecLinkedList
, il est de taille fixe que je donne ici est 2;la source
Je pense que ce que vous décrivez est une file d'attente circulaire. Voici un exemple et voici une meilleure une
la source
Cette classe fait le travail en utilisant la composition au lieu de l'héritage (autres réponses ici), ce qui supprime la possibilité de certains effets secondaires (comme couvert par Josh Bloch dans Essential Java). Le rognage de la LinkedList sous-jacente se produit sur les méthodes add, addAll et offer.
la source
Utilisation et résultat du test:
la source
Sonne comme une liste ordinaire où la méthode add contient un extrait de code supplémentaire qui tronque la liste si elle devient trop longue.
Si cela est trop simple, vous devrez probablement modifier la description de votre problème.
la source
Voir également cette question SO , ou ArrayBlockingQueue ( faites attention au blocage, cela peut être indésirable dans votre cas).
la source
Les exigences que vous avez qui vous ont amené à poser cette question ne sont pas très claires. Si vous avez besoin d'une structure de données de taille fixe, vous pouvez également envisager différentes stratégies de mise en cache. Cependant, comme vous avez une file d'attente, ma meilleure supposition est que vous recherchez un type de fonctionnalité de routeur. Dans ce cas, j'irais avec un tampon en anneau: un tableau qui a un premier et un dernier index. Chaque fois qu'un élément est ajouté, vous incrémentez simplement le dernier index d'élément, et lorsqu'un élément est supprimé, incrémentez le premier index d'élément. Dans les deux cas, l'ajout est effectué en fonction de la taille du tableau, et veillez à incrémenter l'autre index si nécessaire, c'est-à-dire lorsque la file d'attente est pleine ou vide.
De plus, s'il s'agit d'une application de type routeur, vous pouvez également essayer un algorithme tel que Random Early Dropping (RED), qui supprime des éléments de la file d'attente de manière aléatoire avant même qu'elle ne se remplisse. Dans certains cas, RED s'est avéré avoir de meilleures performances globales que la méthode simple permettant à la file d'attente de se remplir avant de tomber.
la source
En fait, vous pouvez écrire votre propre impl basé sur LinkedList, c'est assez simple, il suffit de remplacer la méthode add et de faire le personnel.
la source
Je pense que la meilleure réponse correspondante vient de cette autre question .
Apache commons collections 4 a un CircularFifoQueue qui est ce que vous recherchez. Citant le javadoc:
la source
Une solution simple, ci-dessous est une file d'attente de "String"
Notez que cela ne maintiendra pas l'ordre des éléments dans la file d'attente, mais remplacera l'entrée la plus ancienne.
la source
Comme indiqué dans les POO, nous devrions préférer la composition à l'héritage
Voici ma solution en gardant cela à l'esprit.
la source