[Collections] आकार-सीमित कतार जो जावा में अंतिम एन तत्व रखती है


Answers

अमरूद में अब एक EvictingQueue , एक गैर-अवरुद्ध कतार जो कतार में नए तत्व जोड़ने का प्रयास करते समय स्वचालित रूप से कतार के सिर से तत्वों को स्पष्ट करती है और यह पूर्ण है।

import java.util.Queue;
import com.google.common.collect.EvictingQueue;

Queue<Integer> fifo = EvictingQueue.create(2); 
fifo.add(1); 
fifo.add(2); 
fifo.add(3); 
System.out.println(fifo); 

// Observe the result: 
// [2, 3]
Question

जावा पुस्तकालयों पर एक बहुत ही सरल और त्वरित प्रश्न: क्या एक तैयार वर्ग है जो एक निश्चित अधिकतम आकार के साथ एक Queue लागू करता है - यानी यह हमेशा तत्वों को जोड़ने की अनुमति देता है, लेकिन यह नए जोड़े गए तत्वों के लिए स्थान को समायोजित करने के लिए चुपचाप मुख्य तत्वों को हटा देगा।

बेशक, इसे मैन्युअल रूप से कार्यान्वित करना मुश्किल है:

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;
    }
}

जहां तक ​​मैं देखता हूं, जावा stdlibs में कोई मानक कार्यान्वयन नहीं है, लेकिन अपाचे कॉमन्स में ऐसा कुछ हो सकता है या ऐसा कुछ?




आप MinMaxPriorityQueue से Google Guava से MinMaxPriorityQueue उपयोग कर सकते हैं:

एक न्यूनतम अधिकतम प्राथमिकता कतार अधिकतम आकार के साथ कॉन्फ़िगर किया जा सकता है। यदि ऐसा है, तो प्रत्येक बार कतार का आकार उस मान से अधिक हो जाता है, कतार स्वचालित रूप से इसके तुलनित्र के अनुसार अपने सबसे बड़े तत्व को हटा देती है (जो कि तत्व जो अभी जोड़ा गया हो)। यह परंपरागत बाध्य कतारों से अलग है, जो पूर्ण होने पर नए तत्वों को अवरुद्ध या अस्वीकार करता है।




    public class ArrayLimitedQueue<E> extends ArrayDeque<E> {

    private int limit;

    public ArrayLimitedQueue(int limit) {
        super(limit + 1);
        this.limit = limit;
    }

    @Override
    public boolean add(E o) {
        boolean added = super.add(o);
        while (added && size() > limit) {
            super.remove();
        }
        return added;
    }

    @Override
    public void addLast(E e) {
        super.addLast(e);
        while (size() > limit) {
            super.removeLast();
        }
    }

    @Override
    public boolean offerLast(E e) {
        boolean added = super.offerLast(e);
        while (added && size() > limit) {
            super.pollLast();
        }
        return added;
    }
}



संरचना का विस्तार न करें (हाँ मेरा मतलब है, जावा में कीवर्ड को विस्तारित करने के संदर्भ में और हां यह विरासत है)। संरचना बहुत बढ़िया है क्योंकि यह आपके कार्यान्वयन को पूरी तरह से ढालती है, जिससे आप अपनी कक्षा के उपयोगकर्ताओं को प्रभावित किए बिना कार्यान्वयन को बदल सकते हैं।

मैं इस तरह कुछ करने की सलाह देता हूं (मैं सीधे इस विंडो में टाइप कर रहा हूं, इसलिए खरीदार सिंटैक्स त्रुटियों से सावधान रहें):

public LimitedSizeQueue implements Queue
{
  private int maxSize;
  private LinkedList storageArea;

  public LimitedSizeQueue(final int maxSize)
  {
    this.maxSize = maxSize;
    storageArea = new LinkedList();
  }

  public boolean offer(ElementType element)
  {
    if (storageArea.size() < maxSize)
    {
      storageArea.addFirst(element);
    }
    else
    {
      ... remove last element;
      storageArea.addFirst(element);
    }
  }

  ... the rest of this class

एक बेहतर विकल्प (असफ़ द्वारा दिए गए उत्तर के आधार पर) एक सामान्य वर्ग के साथ अपाचे संग्रह परिपत्रफिफ़ोफर को लपेटना हो सकता है। उदाहरण के लिए:

public LimitedSizeQueue<ElementType> implements Queue<ElementType>
{
    private int maxSize;
    private CircularFifoBuffer storageArea;

    public LimitedSizeQueue(final int maxSize)
    {
        if (maxSize > 0)
        {
            this.maxSize = maxSize;
            storateArea = new CircularFifoBuffer(maxSize);
        }
        else
        {
            throw new IllegalArgumentException("blah blah blah");
        }
    }

    ... implement the Queue interface using the CircularFifoBuffer class
}