Não há implementação existente no Java Language and Runtime. Todas as filas estendem o AbstractQueue e seu documento afirma claramente que a adição de um elemento a uma fila completa sempre termina com uma exceção. Seria melhor (e bastante simples) agrupar uma Fila em uma classe própria para ter a funcionalidade necessária.
Mais uma vez, como todas as filas são filhos do AbstractQueue, basta usá-lo como seu tipo de dados interno e você deverá ter uma implementação flexível em execução praticamente em nenhum momento :-)
ATUALIZAR:
Conforme descrito abaixo, existem duas implementações abertas disponíveis (essa resposta é bastante antiga, pessoal!), Consulte esta resposta para obter detalhes.
@ user7294900 Obrigado, link corrigido. Para sua informação, o Stack Overflow convida você para fazer essas edições diretamente em uma resposta. Qualquer pessoa pode editar, não apenas o autor original. O Stack Overflow destina-se mais à Wikipedia a esse respeito.
Basil Bourque 22/10
@BasilBourque sim, mas essas edições podem ser rejeitadas, mesmo por mim, ao alterar os links, é uma área cinza #
user7294900
18
Acabei de implementar uma fila de tamanho fixo desta maneira:
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);}}
Eu concordo com Amhed acima. Remova o - 1. Caso contrário, na capacidade máxima, você terminará com uma matriz que é maxSize + 1, pois estamos falando de 0 com base. Por exemplo. Se maxSize = 50, ao adicionar um novo objeto, a fórmula removeRange na postagem original será 51 - 50 - 1 = 0 (ou seja, nada foi removido).
Etep
8
Isto é o que eu fiz com Queueembrulhado LinkedList, é de tamanho fixo que eu cito aqui é 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");.....
Essa classe faz o trabalho usando composição em vez de herança (outras respostas aqui), o que remove a possibilidade de certos efeitos colaterais (conforme coberto por Josh Bloch no Essential Java). O corte do LinkedList subjacente ocorre nos métodos add, addAll e offer.
Na verdade, ele precisaria excluir o primeiro elemento (ou seja, o mais antigo), o truncamento removeria o último elemento. Ainda prático com um LinkedList.
Não está claro quais requisitos você o levou a fazer essa pergunta. Se você precisar de uma estrutura de dados de tamanho fixo, também poderá procurar políticas de armazenamento em cache diferentes. No entanto, como você tem uma fila, meu melhor palpite é que você está procurando algum tipo de funcionalidade do roteador. Nesse caso, eu usaria um buffer de anel: uma matriz que possui um primeiro e último índice. Sempre que um elemento é adicionado, você apenas incrementa o índice do último elemento e, quando um elemento é removido, incrementa o índice do primeiro elemento. Nos dois casos, a adição é realizada modulando o tamanho da matriz e certifique-se de incrementar o outro índice quando necessário, ou seja, quando a fila estiver cheia ou vazia.
Além disso, se for um aplicativo do tipo roteador, convém experimentar um algoritmo como o Random Early Dropping (RED), que remove elementos da fila aleatoriamente antes mesmo de ser preenchido. Em alguns casos, verificou-se que o RED possui um desempenho geral melhor do que o método simples de permitir que a fila se encha antes de cair.
Respostas:
Não há implementação existente no Java Language and Runtime. Todas as filas estendem o AbstractQueue e seu documento afirma claramente que a adição de um elemento a uma fila completa sempre termina com uma exceção. Seria melhor (e bastante simples) agrupar uma Fila em uma classe própria para ter a funcionalidade necessária.
Mais uma vez, como todas as filas são filhos do AbstractQueue, basta usá-lo como seu tipo de dados interno e você deverá ter uma implementação flexível em execução praticamente em nenhum momento :-)
ATUALIZAR:
Conforme descrito abaixo, existem duas implementações abertas disponíveis (essa resposta é bastante antiga, pessoal!), Consulte esta resposta para obter detalhes.
fonte
collection.deque
com um especificadomaxlen
.Na verdade, o LinkedHashMap faz exatamente o que você deseja. Você precisa substituir o
removeEldestEntry
métodoExemplo para uma fila com no máximo 10 elementos:
Se "removeEldestEntry" retornar true, a entrada mais antiga será removida do mapa.
fonte
Sim dois
Da minha própria pergunta duplicada com esta resposta correta , aprendi de duas:
EvictingQueue
no Google GuavaCircularFifoQueue
no Apache CommonsFiz uso produtivo da goiaba
EvictingQueue
, funcionou bem.Para instanciar uma
EvictingQueue
chamada, o método estático de fábricacreate
e especifique seu tamanho máximo.fonte
CircularFifoQueue
o link está inoperante, use commons.apache.org/proper/commons-collections/apidocs/org/…Acabei de implementar uma fila de tamanho fixo desta maneira:
fonte
removeRange(0, size() - maxSize)
Isto é o que eu fiz com
Queue
embrulhadoLinkedList
, é de tamanho fixo que eu cito aqui é 2;fonte
Eu acho que o que você está descrevendo é uma fila circular. Aqui está um exemplo e aqui é um melhor um
fonte
Essa classe faz o trabalho usando composição em vez de herança (outras respostas aqui), o que remove a possibilidade de certos efeitos colaterais (conforme coberto por Josh Bloch no Essential Java). O corte do LinkedList subjacente ocorre nos métodos add, addAll e offer.
fonte
Uso e resultado do teste:
fonte
Soa como uma lista comum, em que o método add contém um trecho extra que trunca a lista se ela for muito longa.
Se isso for muito simples, você provavelmente precisará editar a descrição do seu problema.
fonte
Consulte também esta questão do SO , ou ArrayBlockingQueue (tenha cuidado com o bloqueio, isso pode ser indesejável no seu caso).
fonte
Não está claro quais requisitos você o levou a fazer essa pergunta. Se você precisar de uma estrutura de dados de tamanho fixo, também poderá procurar políticas de armazenamento em cache diferentes. No entanto, como você tem uma fila, meu melhor palpite é que você está procurando algum tipo de funcionalidade do roteador. Nesse caso, eu usaria um buffer de anel: uma matriz que possui um primeiro e último índice. Sempre que um elemento é adicionado, você apenas incrementa o índice do último elemento e, quando um elemento é removido, incrementa o índice do primeiro elemento. Nos dois casos, a adição é realizada modulando o tamanho da matriz e certifique-se de incrementar o outro índice quando necessário, ou seja, quando a fila estiver cheia ou vazia.
Além disso, se for um aplicativo do tipo roteador, convém experimentar um algoritmo como o Random Early Dropping (RED), que remove elementos da fila aleatoriamente antes mesmo de ser preenchido. Em alguns casos, verificou-se que o RED possui um desempenho geral melhor do que o método simples de permitir que a fila se encha antes de cair.
fonte
Na verdade, você pode escrever seu próprio impl com base no LinkedList, é bastante direto, basta substituir o método add e fazer a equipe.
fonte
Eu acho que a melhor resposta correspondente é dessa outra pergunta .
O Apache commons collections 4 possui um CircularFifoQueue, que é o que você está procurando. Citando o javadoc:
fonte
Uma solução simples, abaixo, é uma fila de "String"
Observe que isso não manterá a ordem dos itens na fila, mas substituirá a entrada mais antiga.
fonte
Como é recomendado nas OOPs, devemos preferir Composição ao invés de Herança
Aqui está minha solução tendo isso em mente.
fonte