[Java] जावा में रिवर्स ऑर्डर में एक सूची के माध्यम से छेड़छाड़



Answers

Guava Lists#reverse(List) और ImmutableList#reverse() Lists#reverse(List) ImmutableList#reverse() । जैसा कि गुवा के ज्यादातर मामलों में, पूर्व प्रतिनिधियों ने उत्तरार्द्ध के लिए यदि तर्क एक ImmutableList , तो आप सभी मामलों में पूर्व का उपयोग कर सकते हैं। ये सूची की नई प्रतियां नहीं बनाते हैं बल्कि इसके "उलट विचार" भी नहीं बनाते हैं।

उदाहरण

List reversed = ImmutableList.copyOf(myList).reverse();
Question

इस प्रश्न का उत्तर यहां दिया गया है:

मैं जेनेरिकों का उपयोग करने के लिए कोड का एक टुकड़ा माइग्रेट कर रहा हूं। ऐसा करने के लिए एक तर्क यह है कि फॉर लूप इंडेक्स का ट्रैक रखने या स्पष्ट इटरेटर का उपयोग करने से ज्यादा क्लीनर है।

लगभग आधे मामलों में, सूची (एक ऐरेलिस्ट) को आज इंडेक्स का उपयोग करके रिवर्स ऑर्डर में पुनरावृत्त किया जा रहा है।

क्या कोई ऐसा करने का क्लीनर तरीका सुझा सकता है (क्योंकि संग्रह के साथ काम करते समय मैं indexed for loop नापसंद करता हूं), हालांकि यह काम करता है?

 for (int i = nodes.size() - 1; i >= 0; i--) {
    final Node each = (Node) nodes.get(i);
    ...
 }

नोट: मैं जेडीके के बाहर कोई नई निर्भरता नहीं जोड़ सकता।




जैसा कि कम से कम दो बार सुझाव दिया गया है, आप विशेष रूप से एक LinkedList साथ, Deque साथ descendingIterator Deque उपयोग कर सकते हैं। यदि आप प्रत्येक लूप के लिए उपयोग करना चाहते हैं (यानी, एक Iterable ), तो आप इस तरह के Iterable निर्माण और उपयोग कर सकते हैं:

import java.util.*;

public class Main {

    public static class ReverseIterating<T> implements Iterable<T> {
        private final LinkedList<T> list;

        public ReverseIterating(LinkedList<T> list) {
            this.list = list;
        }

        @Override
        public Iterator<T> iterator() {
            return list.descendingIterator();
        }
    }

    public static void main(String... args) {
        LinkedList<String> list = new LinkedList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        list.add("E");

        for (String s : new ReverseIterating<String>(list)) {
            System.out.println(s);
        }
    }
}






कस्टम रिवर्स इटेबल बनाएं




यदि सूचियां काफी छोटी हैं तो प्रदर्शन वास्तविक समस्या नहीं है, तो कोई भी Google Guava में Lists क्लास के reverse मेटोड का उपयोग कर सकता है। for-each कोड के for-each सुंदर बनाता है, और मूल सूची वही रहता है। साथ ही, उल्टा सूची मूल सूची द्वारा समर्थित है, इसलिए मूल सूची में कोई भी परिवर्तन उलटा हुआ प्रतिबिंबित होगा।

import com.google.common.collect.Lists;

[...]

final List<String> myList = Lists.newArrayList("one", "two", "three");
final List<String> myReverseList = Lists.reverse(myList);

System.out.println(myList);
System.out.println(myReverseList);

myList.add("four");

System.out.println(myList);
System.out.println(myReverseList);

निम्नलिखित परिणाम उत्पन्न करता है:

[one, two, three]
[three, two, one]
[one, two, three, four]
[four, three, two, one]

जिसका अर्थ है कि मेरी सूची के विपरीत पुनरावृत्ति को इस प्रकार लिखा जा सकता है:

for (final String someString : Lists.reverse(myList)) {
    //do something
}



बहुत सरल उदाहरण:

List<String> list = new ArrayList<String>();

list.add("ravi");

list.add("kant");

list.add("soni");

// Iterate to disply : result will be as ---     ravi kant soni

for (String name : list) {
  ...
}

//Now call this method

Collections.reverse(list);

// iterate and print index wise : result will be as ---     soni kant ravi

for (String name : list) {
  ...
}



विकल्प 1: क्या आपने Collections#reverse() साथ सूची को वापस करने और फिर foreach का उपयोग करने के बारे में सोचा है?

बेशक, आप अपने कोड को दोबारा प्रतिक्रिया देना चाहेंगे जैसे सूची सही ढंग से आदेशित की जाती है ताकि आपको इसे उलटना न पड़े, जो अतिरिक्त स्थान / समय का उपयोग करता है।

संपादित करें:

विकल्प 2: वैकल्पिक रूप से, क्या आप एक Deque बजाय Deque उपयोग कर सकते हैं? यह आपको आगे और पीछे की ओर इशारा करने की अनुमति देगा

संपादित करें:

विकल्प 3: जैसा कि अन्य ने सुझाव दिया है, आप एक इटरेटर लिख सकते हैं जो सूची में उल्टा हो जाएगा, यहां एक उदाहरण है:

import java.util.Iterator;
import java.util.List;

public class ReverseIterator<T> implements Iterator<T>, Iterable<T> {

    private final List<T> list;
    private int position;

    public ReverseIterator(List<T> list) {
        this.list = list;
        this.position = list.size() - 1;
    }

    @Override
    public Iterator<T> iterator() {
        return this;
    }

    @Override
    public boolean hasNext() {
        return position >= 0;
    }

    @Override
    public T next() {
        return list.get(position--);
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

}


List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");

for (String s : new ReverseIterator<String>(list)) {
    System.out.println(s);
}



Links