जावा की सूची में उलट सूची दृश्य कैसे प्राप्त करें?


214

मैं एक सूची पर एक उल्टा सूची दृश्य रखना चाहता हूं (इसी तरह List#sublistएक सूची पर एक सबलिस्ट दृश्य प्रदान करता है)। क्या कोई फ़ंक्शन है जो इस कार्यक्षमता प्रदान करता है?

मैं सूची की किसी भी प्रकार की प्रतिलिपि नहीं बनाना चाहता और न ही सूची को संशोधित करना चाहता हूं।

यह पर्याप्त होगा यदि मैं इस मामले में एक सूची में कम से कम रिवर्स पुनरावृत्ति प्राप्त कर सकता हूं।


इसके अलावा, मुझे पता है कि इसे कैसे लागू करना है। मैं सिर्फ यह पूछ रहा हूं कि क्या जावा पहले से ही ऐसा कुछ प्रदान करता है।

डेमो कार्यान्वयन:

static <T> Iterable<T> iterableReverseList(final List<T> l) {
    return new Iterable<T>() {
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                ListIterator<T> listIter = l.listIterator(l.size());                    
                public boolean hasNext() { return listIter.hasPrevious(); }
                public T next() { return listIter.previous(); }
                public void remove() { listIter.remove(); }                 
            };
        }
    };
}

मुझे अभी पता चला है कि कुछ Listकार्यान्वयनों descendingIterator()में वही है जो मुझे चाहिए। हालांकि इसके लिए ऐसा कोई सामान्य कार्यान्वयन नहीं है List। यह किस तरह का अजीब है क्योंकि मैंने जिस कार्यान्वयन को देखा है LinkedListवह सामान्य रूप से किसी के साथ काम करने के लिए पर्याप्त है List


1
क्या आप उल्टे क्रम में सूची बनाना शुरू कर सकते हैं?
टोनी एननिस

हाँ यह करता है - java.uitl.List.listIterator (int) download.oracle.com/javase/6/docs/api/java/util/...
TofuBeer

यदि आप इस लिंक पर जाकर सूची को Collections.reverse(list)
उलटते

जवाबों:


210

अमरूद यह प्रदान करता है: Lists.reverse (सूची)

List<String> letters = ImmutableList.of("a", "b", "c");
List<String> reverseView = Lists.reverse(letters); 
System.out.println(reverseView); // [c, b, a]

इसके विपरीत Collections.reverse, यह विशुद्ध रूप से एक दृश्य है ... यह मूल सूची में तत्वों के क्रम में परिवर्तन नहीं करता है। इसके अतिरिक्त, एक मूल सूची जो कि परिवर्तनीय है, मूल सूची और दृश्य दोनों में परिवर्तन दूसरे में परिलक्षित होता है।


11
समस्या यह है कि अमरूद एक बहुत बड़ी लाइब्रेरी है। चर्चा देखें: github.com/google/guava/issues/1954 और code.google.com/p/guava-lbooks/issues/detail?id=605
फ़िलिप ब्रिटो

2
@ फ़ीलिप डी लीमा ब्रिटो: प्रोगार्ड अभी भी पुस्तकालय आकार के लिए सबसे अच्छा समाधान है, हालांकि संभावना है कि हम सुधार कर सकते हैं। किसी भी मामले में, मुझे नहीं लगता कि इस जवाब के लिए पुस्तकालय का आकार किसी भी तरह से प्रासंगिक है।
कॉलिनड जूल

2
हां, लाइब्रेरी का आकार इस उत्तर के लिए प्रासंगिक नहीं है, लेकिन प्रोग्रामर के लिए सूचित किया जाना प्रासंगिक है (इसलिए, मैंने टिप्पणी की)! इस महान पुस्तकालय और आपके सुझाव के लिए बहुत बहुत धन्यवाद @ColinD!
फिलिपो ब्रिटो

@ColinD, हाँ, यह मेरी गलती थी। एक सहकर्मी ने Google-संग्रह जोड़े हैं जिसमें समान नामस्थान और वर्ग ( List) हैं, लेकिन बिना रिवर्स पद्धति के। इसे हटाने से अमरूद फिर से उपलब्ध हो गया।
AAA

डेवलपर्स का हमेशा इस बात पर नियंत्रण नहीं होता है कि वे किन पुस्तकालयों का उपयोग कर सकते हैं, और कुछ के लिए एक पूरी नई लाइब्रेरी को जोड़ना इतना आसान लगता है जैसे ओवरकिल - विशेष रूप से यह देखते हुए कि समस्या को हल किया जा सकता हैListIterator.previous()
जोनाथन बेन्

218

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

Ergo,

Collections.reverse(list.clone());

यदि आप उपयोग कर रहे हैं Listऔर clone()आपके पास पहुंच नहीं है, तो आप इसका उपयोग कर सकते हैं subList():

List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);

21
clone()सामान्य रूप से सूची की एक प्रति बनाएगा। वैसे भी, List#clone()मौजूद नहीं है।
अल्बर्ट

6
आप तकनीकी रूप से सही हैं, सूची इंटरफ़ेस स्वयं क्लोन () विधि प्रदान नहीं करता है। लेकिन ArrayList, LinkedList और वेक्टर सभी करते हैं।
jcalvert

2
मैंने अभी इसके कार्यान्वयन को देखा clone()। यह वास्तव में सूची की एक पूरी प्रतिलिपि करता है (यह केवल सूची में प्रत्येक एकल ऑब्जेक्ट को क्लोन नहीं करता है लेकिन वह कभी भी नहीं था जो मैं बात कर रहा था)।
अल्बर्ट

21
ध्यान दें कि Collections.reverse शून्य हो जाता है, इसलिए आप क्लोन संदर्भ खो देंगे। आपको क्लोन को पहले एक वैरिएबल पर असाइन करने की आवश्यकता है, फिर इसे सॉर्ट करें।
user12722

10
subListकॉपी नहीं करता है, यह सिर्फ अंतर्निहित सूची पर एक दृश्य प्रदान करता है, इसलिए इस दृश्य को उलटने से अंतर्निहित सूची को उलट दिया जाएगा।
रोलैंड

80

अगर मैं सही समझ गया हूं तो यह कोड की एक पंक्ति है। यह मेरे लिए काम करता है।

 Collections.reverse(yourList);

12
वह सूची दृश्य नहीं है। वह सूची को संशोधित करता है।
अल्बर्ट

35

यह बिल्कुल सुरुचिपूर्ण नहीं है, लेकिन यदि आप List.listIterator (int index) का उपयोग करते हैं, तो आप सूची के अंत में एक द्वि-दिशात्मक ListIterator प्राप्त कर सकते हैं:

//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());

while (li.hasPrevious()) {
   String curr = li.previous()
}

1
यह सबसे अच्छा उत्तर है, क्योंकि (1) को पुस्तकालय की आवश्यकता नहीं होती है, और (2) यह मूल सूची को संशोधित नहीं करता है, जैसा कि ओपी ने अनुरोध किया है
जोनाथन बेन्

12

संग्रह.श्रवण (संख्या) ... यह वास्तव में तत्वों के क्रम को उलट देता है। नीचे दिए गए कोड की बहुत सराहना की जानी चाहिए -

List<Integer> nums = new ArrayList<Integer>();
nums.add(61);
nums.add(42);
nums.add(83);
nums.add(94);
nums.add(15);
//Tosort the collections uncomment the below line
//Collections.sort(nums); 

Collections.reverse(nums);

System.out.println(nums);

आउटपुट: 15,94,83,42,61


8
आप केवल उस उत्तर को दोहरा रहे हैं जो किसी और ने 6 साल पहले लिखा था
जोनाथन बेन्

1
... और एक दृश्य नहीं। यह सूची को बदल देता है।
जेसन एस

6

java.util.Dequeहै descendingIterator()- अगर आपका Listएक है Deque, तो आप इसका उपयोग कर सकते हैं।


यदि आप बिल्ट-इन descndingIterator () विधि का उपयोग नहीं करना चाहते हैं, तो ऐसा लगता है कि एक समवर्तीलिंक का उपयोग करना बहुत बड़ी सूची को उलटने के लिए सबसे अच्छा होगा? मूल रूप से सिर्फ एक डेक से नए डेक के लिए पोल का उपयोग कर की पेशकश करते हैं? सॉर्टा जैसे कार्डों का डेक होना और प्रत्येक को एक नए ढेर में क्रम में उतारना।
djangofan

4

मुझे पता है कि यह एक पुरानी पोस्ट है लेकिन आज मैं कुछ इस तरह की तलाश में था। अंत में मैंने खुद कोड लिखा:

private List reverseList(List myList) {
    List invertedList = new ArrayList();
    for (int i = myList.size() - 1; i >= 0; i--) {
        invertedList.add(myList.get(i));
    }
    return invertedList;
}

लंबी सूचियों के लिए अनुशंसित नहीं है, यह बिल्कुल भी अनुकूलित नहीं है। यह नियंत्रित परिदृश्यों के लिए एक आसान समाधान की तरह है (मेरे द्वारा सूचीबद्ध सूचियाँ 100 से अधिक तत्व नहीं हैं)।

आशा है कि यह किसी की मदद करता है।


2
आपके कोड में एक समस्या है - आप इसमें कोई भी सूची डाल सकते हैं, लेकिन यह आपको हमेशा ArrayList (सूची के रूप में) लौटाएगा। और क्या होगा अगर मुझे लिंक्डलिस्ट की आवश्यकता है? MyList को संशोधित करना और शून्य वापस करना बेहतर है।
दिमित्री ज़ेत्सेव

2
ध्यान दें कि यह वास्तव में वह नहीं है जो मैं पूछ रहा था। मैं किसी प्रकार की प्रॉक्सी / देखने के लिए कह रहा था, कॉपी नहीं।
अल्बर्ट

4

मैं इसका उपयोग करता हूं:

public class ReversedView<E> extends AbstractList<E>{

    public static <E> List<E> of(List<E> list) {
        return new ReversedView<>(list);
    }

    private final List<E> backingList;

    private ReversedView(List<E> backingList){
        this.backingList = backingList;
    }

    @Override
    public E get(int i) {
        return backingList.get(backingList.size()-i-1);
    }

    @Override
    public int size() {
        return backingList.size();
    }

}

इस तरह:

ReversedView.of(backingList) // is a fully-fledged generic (but read-only) list

1

आप यह भी कर सकते हैं:

static ArrayList<String> reverseReturn(ArrayList<String> alist)
{
   if(alist==null || alist.isEmpty())
   { 
       return null;
   }

   ArrayList<String> rlist = new ArrayList<>(alist);

   Collections.reverse(rlist);
   return rlist;
}

5
वह सूची दृश्य नहीं है। एक दृश्य एक प्रति के विपरीत है।
अल्बर्ट

खाली सूची की उल्टी सूची शून्य है ??
शेलफिश

1

जब आप किसी वस्तु का अनुरोध करते हैं तो आप स्थिति को उल्टा कर सकते हैं:

Object obj = list.get(list.size() - 1 - position);

1

छोटे आकार की सूची के लिए हम बना सकते हैं LinkedListऔर फिर अवरोही पुनरावृत्ति का उपयोग कर सकते हैं:

List<String> stringList = new ArrayList<>(Arrays.asList("One", "Two", "Three"));
stringList.stream().collect(Collectors.toCollection(LinkedList::new))
         .descendingIterator().
         forEachRemaining(System.out::println); // Three, Two, One
System.out.println(stringList); // One, Two, Three

-3

कक्षा के reverse(...)तरीकों का उपयोग करें java.util.Collections। अपनी सूची को एक पैरामीटर के रूप में पास करें और आपकी सूची उलट हो जाएगी।

Collections.reverse(list);

1
एक मौजूदा उत्तर की प्रतिलिपि
कार्ल रिक्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.