আকার-সীমাবদ্ধ সারি যা জাভাতে সর্বশেষ এন উপাদান ধারণ করে


197

জাভা লাইব্রেরিগুলির একটি খুব সাধারণ এবং দ্রুত প্রশ্ন: একটি প্রস্তুত তৈরি শ্রেণি রয়েছে যা 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;
    }
}

যতদূর আমি দেখছি, জাভা স্টাডলিবগুলিতে কোনও মানক বাস্তবায়ন নেই, তবে অ্যাপাচি কমন্সে একটি বা এরকম কিছু থাকতে পারে?


1
সংশ্লিষ্ট stackoverflow.com/questions/590069/...
andersoj

9
@ কেভিন: আপনি এমন টিজড।
মার্ক পিটারস

5
পার্সোনালালি আমি আর একটি গ্রন্থাগার চালু করতাম না যদি এটি এই লাইব্রেরির একমাত্র ব্যবহার ছিল ...
নিকোলাস বোসকেট

2
@ ওভাররাইড পাবলিক বুলিয়ান অ্যাড (প্রোপাগেশন টাস্ক টি) {বুলিয়ান অ্যাড = সুপার.এডিডি (টি); যখন (যুক্ত && আকার ()> সীমা) - সুপার.রেভ (); } রিটার্ন যুক্ত; }
রেনেউদ

6
সতর্কতা: প্রশ্নযুক্ত কোড, যদিও এটি স্পষ্টতই কাজ করে, এটি পিছিয়ে যেতে পারে। এই অতিরিক্ত আকার রয়েছে যা কাতারে আরও উপাদান যুক্ত করতে পারে (যেমন অ্যাডএল ()) যা এই আকারের চেকটিকে উপেক্ষা করে। আরও তথ্যের জন্য কার্যকর জাভা 2 য় সংস্করণ দেখুন - আইটেম 16: উত্তরাধিকারের
ডিয়েগো

উত্তর:


171

অ্যাপাচি কমন্স সংগ্রহ 4 এর একটি সার্কুলার ফিফিউকিউ <> যা আপনি খুঁজছেন। জাভাডোকের উদ্ধৃতি:

সার্কুলারফাইফিউ কিউ একটি স্থির আকারের সাথে প্রথম-ইন প্রথম-আউট সারি যা পূর্ণ হলে তার প্রাচীনতম উপাদানটি প্রতিস্থাপন করে।

    import java.util.Queue;
    import org.apache.commons.collections4.queue.CircularFifoQueue;

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

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

আপনি যদি অ্যাপাচি কমন্স সংগ্রহের পুরানো সংস্করণ (3.x) ব্যবহার করে থাকেন তবে আপনি সার্কুলারফাইফুফার ব্যবহার করতে পারেন যা জেনারিক ছাড়াই মূলত একই জিনিস।

আপডেট : জেনেরিক্স সমর্থন করে কমন্স সংগ্রহ সংস্করণ 4 প্রকাশের পরে আপডেট হওয়া উত্তর।


1
এটি একটি ভাল প্রার্থী, তবে হায়, এটি
জেনেরিকগুলি

ধন্যবাদ! দেখে মনে হচ্ছে এটি এখনই সবচেয়ে কার্যকর বিকল্প :))
গ্রেগেট 20

3
২০১৩-১০-এর দিকে গুগল পেয়ারা সংস্করণ 15 এ যুক্ত করার জন্য এই অন্যান্য উত্তরটি দেখুন । EvictingQueue
বাসিল বাউরক

পূর্ণ কাতারের পাশাপাশি উপাদানটি সারিবদ্ধ করা হলে সেখানে কি কোনও কলব্যাক বলা হয়?
এডি 22

একটি "সার্কুলার ক্যু" কেবল একটি বাস্তবায়ন যা প্রশ্নের সন্তুষ্ট করে। তবে প্রশ্নটি একটি বিজ্ঞপ্তি সারির মূল পার্থক্যগুলি থেকে সরাসরি উপকৃত হয় না, অর্থাত প্রতিটি বালতি প্রতিটি সংযোজন / মুছে ফেলার ক্ষেত্রে মুক্ত / পুনঃস্থাপন না করে।
সরল ব্যবহারকারীর

90

পেয়ারাতে এখন একটি ইভিচিংকিউ রয়েছে , একটি অ-ব্লকিং ক্যু যা কাতারে নতুন উপাদান যুক্ত করার চেষ্টা করার সময় স্বয়ংক্রিয়ভাবে কাতারের মাথা থেকে উপাদানগুলি সরিয়ে দেয় এবং এটি পূর্ণ।

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]

এটি সরকারীভাবে প্রকাশিত হওয়ার পরে এটি ব্যবহার করা আকর্ষণীয় হওয়া উচিত।
আসফ

এখানে উত্সটি রয়েছে: কোড. google.com/p/guava-libraries/source/browse/guava/src/com/… - দেখে মনে হচ্ছে পেয়ারা
টম ক্র্যাচরে

1
আপডেট: এই শ্রেণিটি গুগল পেয়ারা দিয়ে 2013-10-এর 15 সংস্করণে আনুষ্ঠানিকভাবে প্রকাশ হয়েছিল ।
বাসিল বাউরক

1
@ ম্যাসিজেমিক্লাস প্রশ্নটি একটি ফিফোর জন্য জিজ্ঞাসা করছে, EvictingQueueএটি একটি ফিফো? যদি কোনো সন্দেহ নেই, এই প্রোগ্রামটি দেখুন: Queue<Integer> fifo = EvictingQueue.create(2); fifo.add(1); fifo.add(2); fifo.add(3); System.out.println(fifo); ফলাফলের পালন:[2, 3]
kostmo

2
এটি এখন সঠিক উত্তর। ডকুমেন্টেশন থেকে এটি কিছুটা অস্পষ্ট, তবে EvictingQueue একটি ফিফো।
মাইকেল বেকলিং

11

আমি @ ফ্র্যাক্টালাইজআর সমাধানটি পছন্দ করি। তবে আমি অতিরিক্তটি সুপার.এডিডি (ও) থেকে রাখব এবং ফিরিয়ে দেব!

public class LimitedQueue<E> extends LinkedList<E> {

    private int limit;

    public LimitedQueue(int limit) {
        this.limit = limit;
    }

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

1
আমি যতদূর দেখতে পাচ্ছি, ফ্র্যাক্টালাইজারআর কোনও সমাধান সরবরাহ করেনি, কেবল প্রশ্ন সম্পাদনা করেছেন। প্রশ্ন মধ্যে "সমাধান" হয় না একটি সমাধান, কারণ প্রশ্ন হলো, মান বা অর্ধ-মান লাইব্রেরিতে কিছু বর্গ ব্যবহার করে নিজস্ব ঘূর্ণায়মান না প্রায় দুপুর।
গ্রেটকিট

3
এটি চিহ্নিত করা উচিত যে এই সমাধানটি থ্রেড-নিরাপদ নয়
কনরাড মোরাউস্কি

7
@ কনরাডমোরাউস্কি পুরো লিঙ্কডলিস্ট শ্রেণি যাইহোক থ্রেড-নিরাপদ নয়, সুতরাং আপনার মন্তব্য এই প্রসঙ্গে অর্থহীন!
রেনেউদ

@ রেনাড ব্লু থ্রেড সুরক্ষা একটি বৈধ উদ্বেগ (যদি প্রায়শই উপেক্ষা করা হয়), সুতরাং মন্তব্যটি অর্থহীন বলে আমি মনে করি না। এবং মনে করিয়ে দেওয়া যে LinkedListথ্রেড নিরাপদ নয় তা অর্থহীন হবে না। এই প্রশ্নের প্রসঙ্গে, ওপির নির্দিষ্ট প্রয়োজনীয়তা এটি বিশেষভাবে গুরুত্বপূর্ণ করে তোলে যে কোনও আইটেম যুক্ত করা একটি পারমাণবিক অপারেশন হিসাবে সম্পাদিত হয়। অন্য কথায়, নিয়মিত লিংকডলিস্টের চেয়ে পারমাণবিকতা নিশ্চিত না করার ঝুঁকি বেশি থাকে।
কনরাড মোরাউস্কি

4
add(int,E)পরিবর্তে কেউ কল করার সাথে সাথে ব্রেক হয় । এবং addAllইচ্ছাকৃত হিসাবে কাজ করে কিনা তা অনির্ধারিত বাস্তবায়ন বিশদের উপর নির্ভর করে। এজন্য আপনার উত্তরাধিকারের চেয়ে প্রতিনিধিদের পছন্দ করা উচিত ...
হোলগার

6

রচনাগুলি প্রসারিত হয় না (হ্যাঁ আমি প্রসারিত বলতে চাইছি জাভাতে প্রসারিত কীওয়ার্ডের উল্লেখ হিসাবে এবং হ্যাঁ এটি উত্তরাধিকার)। সংমিশ্রণটি তাত্পর্যপূর্ণ কারণ এটি আপনার বাস্তবায়ন সম্পূর্ণরূপে shাল দেয়, আপনার শ্রেণীর ব্যবহারকারীদের প্রভাবিত না করে আপনাকে বাস্তবায়ন পরিবর্তন করতে দেয়।

আমি এই জাতীয় কিছু চেষ্টা করার পরামর্শ দিচ্ছি (আমি সরাসরি এই উইন্ডোতে টাইপ করছি, তাই ক্রেতা সিনট্যাক্স ত্রুটি থেকে সাবধান থাকুন):

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
}

2
+1 যদি আপনি ব্যাখ্যা করেন কেন রচনাটি আরও ভাল পছন্দ ("উত্তরাধিকারের চেয়ে বেশি রচনা পছন্দ করুন) ... এবং এর খুব ভাল কারণ আছে
কেডগ্রিগরি

1
রচনাটি এখানে আমার কাজের জন্য একটি নিখুঁত পছন্দ: এর অর্থ কমপক্ষে অবজেক্টের সংখ্যার দ্বিগুণ => কমপক্ষে দ্বিগুণ আরও প্রায়শই আবর্জনা সংগ্রহ। আমি সীমিত আকারের এই কিউগুলির বৃহত পরিমাণে (দশ লক্ষ) ব্যবহার করি: মানচিত্র <লং, লিমিটেড সাইজ কিউ <স্ট্রিং>>।
গ্রেগেট

@ গ্রেগেট - আমি তা গ্রহণ করেছি যে আপনি কীভাবে LinkedListবাস্তবায়িত হয় সেদিকে নজর দেননি । তালিকার চারপাশে মোড়ক হিসাবে তৈরি করা অতিরিক্ত বস্তুটি "দশ লক্ষ লক্ষ" উদাহরণ সহ, এমনকি বেশ ছোটখাটো হবে।
kdgregory

আমি "ইন্টারফেসের আকার হ্রাস করে" যাচ্ছিলাম, তবে "বাস্তবায়নের shালগুলি" একই জিনিস। হয় অপার পদ্ধতির বিষয়ে মার্ক পিটারের অভিযোগের উত্তর দিন।
kdgregory

4

কেবলমাত্র আমি জানি যে সীমিত স্থান রয়েছে তা হ'ল ব্লকিংকুইউ ইন্টারফেস (যা উদাহরণস্বরূপ অ্যারেব্লকিংকিউ ক্লাস দ্বারা প্রয়োগ করা হয়) - তবে তারা পূরণ করা প্রথম উপাদানটিকে সরাবে না, পরিবর্তে স্থান অপরিশোধিত হওয়া অবধি অপারেশনটিকে অবরুদ্ধ করবে (অন্য থ্রেড দ্বারা অপসারণ করা হবে) )।

আমার জ্ঞানের কাছে আপনার তুচ্ছ বাস্তবায়ন হ'ল এই জাতীয় আচরণের সবচেয়ে সহজ উপায়।


আমি ইতিমধ্যে জাভা stdlib ক্লাস মাধ্যমে ব্রাউজ করেছি, এবং, দুঃখের বিষয়, BlockingQueueএকটি উত্তর না। আমি অন্যান্য সাধারণ লাইব্রেরিগুলির কথা চিন্তা করেছি, যেমন অ্যাপাচি কমন্স, এক্লিপসের লাইব্রেরি, স্প্রিংস, গুগলের সংযোজন ইত্যাদি?
গ্রেটকিট

3

জাভাডোক থেকে আপনি গুগল পেয়ারা থেকে একটি মিনিম্যাক্সপ্রিয়রিটিউইউ ব্যবহার করতে পারেন :

একটি সর্বনিম্ন সর্বোচ্চ অগ্রাধিকার সারি সর্বাধিক আকারের সাথে কনফিগার করা যেতে পারে। যদি তা হয়, প্রতিবারের মতো কাতারের আকারটি সেই মানটি অতিক্রম করে, কাতারটি তার তুলনাকারী অনুসারে স্বয়ংক্রিয়ভাবে তার বৃহত্তম উপাদানটি সরিয়ে দেয় (যা সম্ভবত সবেমাত্র যুক্ত হওয়া উপাদান হতে পারে)। এটি প্রচলিত সীমানাযুক্ত সারিতে পৃথক, যা পূর্ণ হলে নতুন উপাদানগুলিকে ব্লক করে দেয় বা প্রত্যাখ্যান করে।


3
আপনি কী অগ্রাধিকারের সারিটি বোঝেন এবং এটি ওপির উদাহরণ থেকে কীভাবে আলাদা?
kdgregory

2
@ মার্ক পিটারস - আমি কী বলব তা ঠিক জানি না। অবশ্যই, আপনি একটি অগ্রাধিকার সারিটি ফিফো সারির মতো আচরণ করতে পারেন। আপনি একটি Mapমত একটি আচরণ করতে পারেList । তবে উভয় ধারণা আলগোরিদিম এবং সফ্টওয়্যার ডিজাইনের সম্পূর্ণ বোধগম্যতা দেখায়।
kdgregory

2
@ মার্ক পিটারস - এস সম্পর্কে প্রতিটি প্রশ্ন নয় কিছু করার ভাল উপায় নয়?
jtahlorn

3
@ জেতাহলবোন: স্পষ্টতই (কোড গল্ফ) নয়, তবে তারা ভাল হলেও একটি কালো এবং সাদা মানদণ্ড নয়। একটি নির্দিষ্ট প্রকল্পের জন্য, ভালটির অর্থ "সবচেয়ে দক্ষ" হতে পারে, অন্যটির অর্থ "বজায় রাখা সবচেয়ে সহজ" এবং অন্য কোনওটির অর্থ হতে পারে "বিদ্যমান গ্রন্থাগারগুলির সাথে কোডের ন্যূনতম পরিমাণ" mean এগুলি অপ্রাসঙ্গিক যেহেতু আমি কখনও বলিনি যে এটি একটি ভাল উত্তর ছিল। আমি কেবল বলেছি এটি খুব বেশি প্রচেষ্টা ছাড়াই সমাধান হতে পারে। একটি বাঁক MinMaxPriorityQueueকি ওপি চায় মধ্যে একটি পরিবর্তন চেয়ে বেশি তুচ্ছ হয় LinkedList(ওপি এর কোড এমনকি বন্ধ আসে না)।
মার্ক পিটার্স

3
সম্ভবত আপনি ছেলেরা আমার ব্যবহারের শব্দগুলি "অনুশীলনে যা প্রায় অবশ্যই যথেষ্ট হবে" পরীক্ষা করে দেখছেন। আমি এই অর্থটি বোঝাতে চাইনি যে এই সমাধানটি অবশ্যই ওপি'র সমস্যা বা সাধারণভাবে যথেষ্ট হবে। আমি longআমার নিজের পরামর্শ অনুসারে একটি কার্সার টাইপ হিসাবে অবতরণের পছন্দটি উল্লেখ করে বলছিলাম যে এটি অনুশীলনে যথেষ্ট প্রশস্ত হবে যদিও তাত্ত্বিকভাবে আপনি এই সারিতে 2 ^ 64 এরও বেশি অবজেক্ট যুক্ত করতে পারেন যেখানে সমাধানটি ভেঙে যাবে would ।
চিহ্নিত করুন পিটারস

3

অ্যাপাচি কমন্স থেকেও একটি এলআরএমএপ হ'ল আরেকটি সম্ভাবনা।

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/LRUMap.html


আমি কীভাবে LRUMap কে কীভাবে সারি হিসাবে অভিনয় করতে পারি তা সত্যিই বুঝতে পারি না এবং আমার ধারণা এটি সম্ভব হলেও এটি ব্যবহার করা বরং আরও শক্ত হবে।
গ্রেগেট

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

3
প্রশ্নটি ছিল জনপ্রিয় সংগ্রহ শ্রেণীর পাঠাগারগুলির ক্লাস সম্পর্কে, নিজস্ব ঘূর্ণায়মান নয় - ন্যূনতম হোমব্রিউ "সমাধান" ইতিমধ্যে প্রশ্নটিতে সরবরাহ করা হয়েছিল।
গ্রেইগ্যাট

2
গুগল অন্য
পৃষ্ঠাগুলিতেও

1
এই উত্তরটি নিম্ন মানের পর্যালোচনা সারিতে পরিণত হয়েছে সম্ভবতঃ আপনি কোডটির কোনও ব্যাখ্যা সরবরাহ করেন না বলে। যদি এই কোডটি প্রশ্নের উত্তর দেয় তবে আপনার উত্তরে কোডটি ব্যাখ্যা করে কিছু পাঠ্য যুক্ত করার বিষয়ে বিবেচনা করুন। এইভাবে, আপনি আরও বেশি কিছু পাওয়ার সম্ভাবনা বেশি - এবং প্রশ্নকারীকে নতুন কিছু শিখতে সহায়তা করুন।
lmo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.