জাভাতে কোনও তালিকায় বিপরীত তালিকার ভিউ কীভাবে পাবেন?


214

আমি একটি তালিকায় বিপরীত তালিকার ভিউ রাখতে চাই (একইভাবে List#sublistতালিকাতে একটি সাবলিস্ট ভিউ সরবরাহ করে)। এই কার্যকারিতা সরবরাহ করে এমন কিছু ফাংশন আছে কি?

আমি তালিকার কোনও ধরণের অনুলিপি তৈরি করতে বা তালিকাটি পরিবর্তন করতে চাই না।

যদিও আমি এই ক্ষেত্রে একটি তালিকায় কমপক্ষে একটি বিপরীত পুনরাবৃত্তি পেতে পারি তা যথেষ্ট হবে।


এছাড়াও, আমি নিজেও এটি বাস্তবায়ন করতে জানি know আমি শুধু জিজ্ঞাসা করছি জাভা ইতিমধ্যে এরকম কিছু সরবরাহ করে কিনা।

ডেমো বাস্তবায়ন:

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/…
তোফুবিয়ার

আপনি কীভাবে তালিকার বিপরীত (সংশোধন) করবেন তার উত্তর খুঁজতে এই লিঙ্কটিতে যান, এই উত্তরটি:Collections.reverse(list)
ঝাওগ্যাং

উত্তর:


209

পেয়ারা এটি সরবরাহ করে: তালিকাগুলি.বিপরীত (তালিকা)

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 এবং কোড. google.com/p/guava-libraries/issues/detail?id=605
ফিলিপ ব্রিটো

2
@ ফিলিপ ডি লিমা ব্রিটো: লাইব্রেরির আকারের জন্য প্রোগুয়ার্ড এখনও সেরা সমাধান, যদিও আমরা সম্ভবত কিছু উন্নতি করতে পারি। যাই হোক না কেন, আমি মনে করি না যে এই উত্তরটির সাথে কোনওভাবেই লাইব্রেরির আকার প্রাসঙ্গিক।
কলিনড

2
হ্যাঁ, লাইব্রেরির আকার এই উত্তরের সাথে প্রাসঙ্গিক নয়, তবে প্রোগ্রামারদের জন্য অবহিত করা প্রাসঙ্গিক (সুতরাং, আমি মন্তব্য করেছি)! এই দুর্দান্ত লাইব্রেরির জন্য এবং আপনার পরামর্শের জন্য আপনাকে অনেক ধন্যবাদ!
ফিলিপ ব্রিটো

@ কলিনড, হ্যাঁ, এটি আমার ভুল ছিল। একজন সহকর্মী গুগল-সংগ্রহগুলি যুক্ত করেছেন যার একই নামস্থান এবং শ্রেণি ( List) রয়েছে তবে বিপরীত পদ্ধতি ছাড়াই। এটি মুছে ফেলা আবার পেয়ারা উপলব্ধ।
এএএ

বিকাশকারীরা কোন লাইব্রেরি তারা ব্যবহার করতে পারে তার উপর সর্বদা নিয়ন্ত্রণ থাকে না এবং এত সাধারণ কোনও কিছুর জন্য একটি সম্পূর্ণ নতুন লাইব্রেরি যুক্ত করা অতিরিক্ত ওষুধের মতো বলে মনে হয় - বিশেষত প্রদত্ত যে সমস্যার সমাধান করা যেতে পারেListIterator.previous()
জোনাথন বেন

218

আপনার তালিকায় .clone () পদ্ধতিটি ব্যবহার করুন। এটি একটি অগভীর অনুলিপি ফিরে আসবে, এর অর্থ এটিতে একই বস্তুর পয়েন্টার থাকবে, সুতরাং আপনাকে তালিকাটি অনুলিপি করতে হবে না। তারপরে কেবল সংগ্রহগুলি ব্যবহার করুন।

অতএব,

Collections.reverse(list.clone());

আপনি যদি একটি ব্যবহার করছেন Listএবং অ্যাক্সেস না থাকলে clone()আপনি এটি ব্যবহার করতে পারেন subList():

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

21
clone()সাধারণত তালিকার একটি অনুলিপি তৈরি করত। যাইহোক, List#clone()এছাড়াও বিদ্যমান নেই।
অ্যালবার্ট

6
আপনি প্রযুক্তিগতভাবে সঠিক, তালিকা ইন্টারফেস নিজেই ক্লোন () পদ্ধতি সরবরাহ করে না। তবে অ্যারেলিস্ট, লিংকডলিস্ট এবং ভেক্টর সবই করেন।
jcalvers

2
আমি সবেমাত্র বাস্তবায়ন সন্ধান করেছি clone()। এটি প্রকৃতপক্ষে তালিকার সম্পূর্ণ অনুলিপি করে (এটি কেবলমাত্র তালিকার প্রতিটি একক বস্তুকেই ক্লোন করে না তবে এটি আমি কখনই বলছিলাম না)।
অ্যালবার্ট

21
দ্রষ্টব্য: সংগ্রহগুলি রিভার্স বাতিল হয়ে যায়, তাই আপনি ক্লোন রেফারেন্সটি হারাবেন। আপনাকে প্রথমে ভেরিয়েবলের ক্লোন নির্ধারণ করতে হবে, তারপরে এটি বাছাই করুন।
ব্যবহারকারী 12722

10
subListঅনুলিপি করে না, এটি কেবল অন্তর্নিহিত তালিকায় একটি ভিউ সরবরাহ করে, সুতরাং এই দর্শনটিকে বিপরীত করা অন্তর্নিহিত তালিকার বিপরীত হবে।
রোল্যান্ড

80

যদি আমি সঠিক বুঝতে পারি তবে এটি কোডের এক লাইন I এটি আমার পক্ষে কাজ করেছে।

 Collections.reverse(yourList);

12
এটি কোনও তালিকার ভিউ নয়। যে তালিকা পরিবর্তন করে।
অ্যালবার্ট

35

এটি হুবহু মার্জিত নয়, তবে আপনি যদি list.listIterator (int সূচি) ব্যবহার করেন তবে আপনি তালিকার শেষ পর্যন্ত দ্বি-দিকনির্দেশনাযুক্ত তালিকাগ্রাহক পেতে পারেন:

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

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

1
এটি সর্বোত্তম উত্তর, যেহেতু (1) এটির জন্য কোনও গ্রন্থাগারের প্রয়োজন হয় না এবং (২) এটি ওপেন অনুরোধ অনুসারে মূল তালিকাটি পরিবর্তন করে না
জোনাথন বেন

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আপনি এটি ব্যবহার করতে পারেন।


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

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
আপনার কোডের একটি সমস্যা আছে - আপনি এটিতে কোনও তালিকা রাখতে পারেন তবে এটি সর্বদা আপনাকে অ্যারেলিস্ট (তালিকা হিসাবে) ফিরিয়ে দেবে। এবং যদি আমার লিঙ্কলিস্ট দরকার হয়? মাইলিস্টটি সংশোধন করা এবং অকার্যকর ফিরে আসা ভাল।
দিমিত্রি জায়েতসেভ

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
বিদ্যমান উত্তরের অনুলিপি
কার্ল রিখটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.