जवाबों:
जावा भाषा और रनटाइम में कोई मौजूदा कार्यान्वयन नहीं है। सभी क्वीन्स AbstractQueue का विस्तार करते हैं , और इसका डॉक्टर स्पष्ट रूप से कहता है कि एक तत्व को एक पूर्ण कतार में जोड़ना हमेशा एक अपवाद के साथ समाप्त होता है। यह सबसे अच्छा (और काफी सरल) होगा कि आप अपनी जरूरत की कार्यक्षमता के लिए क्यू को अपनी खुद की कक्षा में लपेटें।
एक बार फिर, क्योंकि सभी कतार AbstractQueue के बच्चे हैं, बस इसे अपने आंतरिक डेटा प्रकार के रूप में उपयोग करें और आपके पास एक लचीला कार्यान्वयन होना चाहिए वस्तुतः कुछ ही समय में चल रहा है :-)
अपडेट करें:
जैसा कि नीचे उल्लिखित है, दो खुले कार्यान्वयन उपलब्ध हैं (यह उत्तर काफी पुराना है, लोग!), विवरण के लिए इस उत्तर को देखें।
collection.deque
एक निर्दिष्ट के साथ उपयोग कर सकते हैं maxlen
।
वास्तव में LinkedHashMap वही करता है जो आप चाहते हैं। आपको ओवरराइड करने की आवश्यकता हैremoveEldestEntry
विधि ।
अधिकतम 10 तत्वों वाली कतार के लिए उदाहरण:
queue = new LinkedHashMap<Integer, String>()
{
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, String> eldest)
{
return this.size() > 10;
}
};
यदि "RemoveEldestEntry" सत्य है, तो मैप से सबसे बड़ी प्रविष्टि को हटा दिया जाता है।
से मेरे अपने डुप्लिकेट प्रश्न के साथ इस सही जवाब , मैं दो का पता चला:
मैंने अमरूद का उत्पादक उपयोग किया EvictingQueue
किया, अच्छा काम किया।
एक दृष्टांत के लिए EvictingQueue
कॉल स्थिर कारखाने विधि create
और अपने अधिकतम आकार निर्दिष्ट करें।
EvictingQueue< Person > people = com.google.common.collect.EvictingQueue.create( 100 ) ; // Set maximum size to 100.
CircularFifoQueue
लिंक मृत है, इसके बजाय commons.apache.org/proper/commons-collections/apidocs/org/… का
मैंने अभी एक निश्चित आकार की कतार को इस तरह लागू किया है:
public class LimitedSizeQueue<K> extends ArrayList<K> {
private int maxSize;
public LimitedSizeQueue(int size){
this.maxSize = size;
}
public boolean 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);
}
}
removeRange(0, size() - maxSize)
यह वही है जो मैंने Queue
लिपटा हुआ था LinkedList
, यह निश्चित आकार है जो मैं यहाँ देता हूं 2 है;
public static Queue<String> pageQueue;
pageQueue = new LinkedList<String>(){
private static final long serialVersionUID = -6707803882461262867L;
public boolean 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");
.....
यह वर्ग वंशानुक्रम (यहां अन्य उत्तरों) के बजाय रचना का उपयोग करके काम करता है जो कुछ साइड-इफेक्ट्स की संभावना को दूर करता है (जैसा कि आवश्यक रूप से जोश बलोच द्वारा आवश्यक जावा में कवर किया गया है)। अंतर्निहित लिंक्डलिस्ट की ट्रिमिंग मेथड ऐड, ऐडऑल और ऑफर पर होती है।
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
public class LimitedQueue<T> implements Queue<T>, Iterable<T> {
private final int limit;
private final LinkedList<T> list = new LinkedList<T>();
public LimitedQueue(int limit) {
this.limit = limit;
}
private boolean trim() {
boolean changed = list.size() > limit;
while (list.size() > limit) {
list.remove();
}
return changed;
}
@Override
public boolean add(T o) {
boolean changed = list.add(o);
boolean trimmed = trim();
return changed || trimmed;
}
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public boolean contains(Object o) {
return list.contains(o);
}
@Override
public Iterator<T> iterator() {
return list.iterator();
}
@Override
public Object[] toArray() {
return list.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
@Override
public boolean remove(Object o) {
return list.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return list.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends T> c) {
boolean changed = list.addAll(c);
boolean trimmed = trim();
return changed || trimmed;
}
@Override
public boolean removeAll(Collection<?> c) {
return list.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return list.retainAll(c);
}
@Override
public void clear() {
list.clear();
}
@Override
public boolean offer(T e) {
boolean changed = list.offer(e);
boolean trimmed = trim();
return changed || trimmed;
}
@Override
public T remove() {
return list.remove();
}
@Override
public T poll() {
return list.poll();
}
@Override
public T element() {
return list.element();
}
@Override
public T peek() {
return list.peek();
}
}
public class CircularQueue<E> extends LinkedList<E> {
private int capacity = 10;
public CircularQueue(int capacity){
this.capacity = capacity;
}
@Override
public boolean add(E e) {
if(size() >= capacity)
removeFirst();
return super.add(e);
}
}
उपयोग और परीक्षण के परिणाम:
public static void main(String[] args) {
CircularQueue<String> queue = new CircularQueue<>(3);
queue.add("a");
queue.add("b");
queue.add("c");
System.out.println(queue.toString()); //[a, b, c]
String first = queue.pollFirst(); //a
System.out.println(queue.toString()); //[b,c]
queue.add("d");
queue.add("e");
queue.add("f");
System.out.println(queue.toString()); //[d, e, f]
}
एक साधारण सूची की तरह लगता है जहां ऐड विधि में एक अतिरिक्त स्निपेट होता है जो सूची को बहुत लंबा कर देता है।
यदि यह बहुत सरल है, तो आपको संभवतः अपनी समस्या का विवरण संपादित करना होगा।
इसके अलावा इस SO प्रश्न , या ArrayBlockingQueue को देखें (अवरुद्ध होने के बारे में सावधान रहें, यह आपके मामले में अवांछित हो सकता है)।
यह बिल्कुल स्पष्ट नहीं है कि आपके पास ऐसी कौन सी आवश्यकताएं हैं जिनके कारण आप यह प्रश्न पूछ सकते हैं। यदि आपको एक निश्चित आकार की डेटा संरचना की आवश्यकता है, तो आप विभिन्न कैशिंग नीतियों को भी देखना चाहते हैं। हालाँकि, जब से आपके पास एक कतार है, मेरा सबसे अच्छा अनुमान यह है कि आप किसी प्रकार की राउटर कार्यक्षमता की तलाश कर रहे हैं। उस मामले में, मैं एक रिंग बफर के साथ जाऊंगा: एक ऐसा सरणी जिसमें पहले और अंतिम सूचकांक हैं। जब भी कोई तत्व जोड़ा जाता है, तो आप अंतिम तत्व सूचकांक को बढ़ाते हैं, और जब कोई तत्व हटा दिया जाता है, तो पहले तत्व सूचकांक को बढ़ाते हैं। दोनों ही मामलों में, इसके अलावा सरणी आकार modulo किया जाता है, और जब आवश्यक है, जब कतार पूर्ण या खाली है, तो अन्य सूचकांक को बढ़ाने के लिए सुनिश्चित करें।
इसके अलावा, यदि यह एक राउटर-प्रकार का अनुप्रयोग है, तो आप रैंडम अर्ली ड्रोपिंग (RED) जैसे एल्गोरिथ्म के साथ प्रयोग करना चाह सकते हैं, जो कतार से तत्वों को भरने से पहले ही बेतरतीब ढंग से छोड़ देता है। कुछ मामलों में, RED को छोड़ने से पहले कतार को भरने की अनुमति देने की सरल विधि की तुलना में बेहतर समग्र प्रदर्शन पाया गया है।
मुझे लगता है कि सबसे अच्छा मिलान उत्तर इस अन्य प्रश्न से है ।
Apache commons collection 4 में एक CircularFifoQueue है जिसे आप ढूंढ रहे हैं। जावदोक का उद्धरण:
CircularFifoQueue एक निश्चित आकार के साथ पहली-पहली पहली कतार में है जो पूर्ण होने पर अपने सबसे पुराने तत्व को बदल देता है।
एक सरल समाधान, नीचे "स्ट्रिंग" की एक कतार है
LinkedHashMap<Integer, String> queue;
int queueKeysCounter;
queue.put(queueKeysCounter++, "My String");
queueKeysCounter %= QUEUE_SIZE;
ध्यान दें कि यह कतार में आइटमों के क्रम को बनाए नहीं रखेगा, लेकिन यह सबसे पुरानी प्रविष्टि को बदल देगा।
जैसा कि ओओपी में यह सलाह दी जाती है कि हमें इनहेरिटेंस पर रचना पसंद करनी चाहिए
यहाँ मेरा समाधान यह ध्यान में रखते हुए।
package com.choiceview;
import java.util.ArrayDeque;
class Ideone {
public static void main(String[] args) {
LimitedArrayDeque<Integer> q = new LimitedArrayDeque<>(3);
q.add(1);
q.add(2);
q.add(3);
System.out.println(q);
q.add(4);
// First entry ie 1 got pushed out
System.out.println(q);
}
}
class LimitedArrayDeque<T> {
private int maxSize;
private ArrayDeque<T> queue;
private LimitedArrayDeque() {
}
public LimitedArrayDeque(int maxSize) {
this.maxSize = maxSize;
queue = new ArrayDeque<T>(maxSize);
}
public void add(T t) {
if (queue.size() == maxSize) {
queue.removeFirst();
}
queue.add(t);
}
public boolean remove(T t) {
return queue.remove(t);
}
public boolean contains(T t) {
return queue.contains(t);
}
@Override
public String toString() {
return queue.toString();
}
}