मेरे पास सूची के तत्व के लिए एक सूची और सूचक है। समय-समय पर मुझे चाहिए:

  • कतार के अंत में एक मान जोड़ें
  • कतार के प्रमुख से एक मान निकालें
  • सूचक को सूची में अगले मान पर आगे बढ़ाएं

अर्थात्:

  • WRITE की दृष्टि से यह एक कतार है।
  • पढ़ने के दृष्टिकोण से यह एक सूची है।

यदि मैं सामान्य इटरेटर का उपयोग करता हूं तो कतार को संशोधित करते समय मुझे ConcurrentModificationException मिलता है; अगर मैं ListIterator का उपयोग करता हूं तो मैं केवल पुनरावर्तक स्थिति पर मूल्य हटा/जोड़ सकता हूं।

क्या कोई मानक डेटा संरचना है जिसका उपयोग मैं इसे प्राप्त करने के लिए कर सकता हूं?

0
Jack 27 अप्रैल 2018, 13:21

3 जवाब

सबसे बढ़िया उत्तर

आप एक ConcurrentLinkedQueue का उपयोग कर सकते हैं। यह एक ही समय में संशोधित और पुनरावृति की अनुमति देता है क्योंकि इसमें सिंक्रनाइज़ेशन के लिए आवश्यक तंत्र शामिल हैं।

फॉलोइन स्निपेट एक कामकाजी उदाहरण दिखाता है जहां बिना किसी समस्या के एक ही कतार तक पहुंचने वाले 3 थ्रेड हैं: 1. तत्वों को पुनरावृत्त करना और आउटपुट करना 2. थोड़ी देर में नए तत्व जोड़ना 3. आउटपुट तत्वों को एक बार में हटाना

package test;

import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class QueueListTest
{
    // private static final Queue<Integer> numbers = new ConcurrentLinkedQueue<>();

    public static void main(String[] args)
    {
        final Queue<Integer> numbers = new ConcurrentLinkedQueue<>();

        final AtomicInteger insert = new AtomicInteger(0);
        final AtomicInteger output = new AtomicInteger();

        for(int j = 0; j < 100; j++)
        {
            numbers.add(insert.getAndIncrement());
        }

        // print 1 number every 100ms
        Thread t1 = new Thread() {
            public void run()
            {
                Iterator<Integer> iter = numbers.iterator();
                while(iter.hasNext())
                {

                        int first = numbers.peek();
                        int size = numbers.size();
                        int last = first + size - 1;
                        int current = iter.next();

                        System.out.println("list from " + first + " to " + last + " @ " + current);
                        output.set(current);

                    try
                    {
                        Thread.sleep(100);
                    }
                    catch(InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        };

        // add 5 number every 500ms
        Thread t2 = new Thread() {
            public void run()
            {
                while(true)
                {
                    for(int j = 0; j < 5; j++)
                    {
                        numbers.add(insert.getAndIncrement());
                    }
                    try
                    {
                        Thread.sleep(500);
                    }
                    catch(InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        };

        // remove all printed numbers every 1000ms
        Thread t3 = new Thread() {
            public void run()
            {
                while(true)
                {
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch(InterruptedException e)
                    {
                        e.printStackTrace();
                    }

                        int current = output.intValue();

                        while(numbers.peek() < current)
                            numbers.poll();
                }
            }
        };

        t1.start();
        t2.start();
        t3.start();

        try
        {
            t1.join();
            t2.join();
            t3.join();
        }
        catch(InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

क्यूंकि क्यू "लिंक्ड" है, इसे निरंतर समय में पुनरावृति, जोड़ना और हटाना को संभालना चाहिए और इसलिए यह सबसे कुशल कार्यान्वयन है जिसका आप उपयोग कर सकते हैं।

1
ultimate 27 अप्रैल 2018, 15:49

ज़रुरी नहीं। समस्या यह है कि ऐसी कोई संरचना नहीं है जो वह करती है जो आप कुशल तरीके से चाहते हैं।

  • आप ArrayList का उपयोग कर सकते हैं, सूचकांकों पर पुनरावृति कर सकते हैं और शुरुआत में डालने के बाद एक अद्यतन वर्तमान सूचकांक रख सकते हैं (1 से वृद्धि), लेकिन शुरुआत में सम्मिलित करना कुशल नहीं होगा
  • आप LinkedList का उपयोग नहीं कर सकते क्योंकि यह वर्तमान Node को उजागर नहीं करता है

आपका सबसे अच्छा दांव शायद अपाचे कॉमन्स कलेक्शंस (https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/list/CursorableLinkedList.html)

1
Piotr Wilkin 27 अप्रैल 2018, 13:50

वस्तुओं पर पुनरावृति करने से पहले अपनी सूची की एक प्रति बनाएँ।

या क्या आपके पास कोई अन्य बाधा है?

0
grthr 27 अप्रैल 2018, 13:26