বিপরীত ক্রমে জাভাতে প্রতিটি লুপের জন্য একজন কী করতে পারে?


148

আমার জাভা ব্যবহার করে বিপরীতে ক্রমের তালিকার মাধ্যমে চালানো দরকার।

সুতরাং যেখানে এটি এটি এগিয়ে দেয়:

for(String string: stringList){
//...do something
}

প্রতিটি সিনট্যাক্সের জন্য ব্যবহার করে বিপরীত ক্রমে স্ট্রিংলিস্টটি পুনরাবৃত্তি করার কোনও উপায় আছে ?

স্বচ্ছতার জন্য: আমি জানি কিভাবে বিপরীত ক্রমে কোনও তালিকা পুনরাবৃত্তি করতে হয় তবে জানতে চাই (কৌতূহলের জন্য) প্রতিটি শৈলীর জন্য এটি কীভাবে করা যায় ।


5
"প্রত্যেকের জন্য" লুপের বিন্দুটি হ'ল আপনাকে কেবল প্রতিটি উপাদানটিতে একটি অপারেশন করা দরকার, এবং ক্রমটি গুরুত্বপূর্ণ নয়। এর জন্য প্রতিটি সম্পূর্ণরূপে এলোমেলোভাবে উপাদানগুলিতে প্রক্রিয়া করতে পারে এবং এটি এখনও এটির জন্য ডিজাইন করা হয়েছে। যদি আপনাকে কোনও নির্দিষ্ট উপায়ে উপাদানগুলি প্রক্রিয়া করার প্রয়োজন হয় তবে আমি এটি ম্যানুয়ালি করার পরামর্শ দেব।
মিউসবোল্লা

জাভা সংগ্রহ লাইব্রেরি। ভাষার সাথে আসলে কিছুই করার নেই। দোষ জোশ ব্লচকে।
টম হাটিন -

7
@muusbolla কিন্তু হিসাবে একটি তালিকা একটি হল আদেশ সংগ্রহ, নিশ্চয় তার আদেশ সম্মান জানানো হবে, নির্বিশেষে? সুতরাং প্রতিটি জন্য একটি এলোমেলো ক্রমে তালিকার উপাদানগুলি প্রক্রিয়া করবে না।
লি কোয়ালকভস্কি

5
পছন্দ করেছেন হতে পারে Setউদ্ভূত সংগ্রহের ক্ষেত্রে । সংগ্রহের পদ্ধতি foreachথেকে পুনরাবৃত্তির ক্রমের পুনরাবৃত্তির গ্যারান্টি দেয় iterator()docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html
রবার্ট

উত্তর:


151

কালেকশনস.রেভার পদ্ধতিটি মূল তালিকার উপাদানগুলিকে বিপরীত ক্রমে অনুলিপি করা সহ একটি নতুন তালিকার প্রত্যাবর্তন করে, সুতরাং এটি মূল তালিকার আকারের সাথে ও (এন) কর্মক্ষমতা রয়েছে।

আরও দক্ষ সমাধান হিসাবে, আপনি একটি সজ্জনকারী লিখতে পারেন যা কোনও তালিকার একটি বিপরীত দৃষ্টিভঙ্গিকে স্বাদহীন হিসাবে উপস্থাপন করে। আপনার সাজসজ্জার দ্বারা ফেরানো পুনরাবৃত্তকারীগুলি বিপরীত ক্রমে উপাদানগুলির উপর দিয়ে হাঁটতে সজ্জিত তালিকার তালিকার তালিকা ব্যবহার করবে।

উদাহরণ স্বরূপ:

public class Reversed<T> implements Iterable<T> {
    private final List<T> original;

    public Reversed(List<T> original) {
        this.original = original;
    }

    public Iterator<T> iterator() {
        final ListIterator<T> i = original.listIterator(original.size());

        return new Iterator<T>() {
            public boolean hasNext() { return i.hasPrevious(); }
            public T next() { return i.previous(); }
            public void remove() { i.remove(); }
        };
    }

    public static <T> Reversed<T> reversed(List<T> original) {
        return new Reversed<T>(original);
    }
}

এবং আপনি এটি ব্যবহার করুন:

import static Reversed.reversed;

...

List<String> someStrings = getSomeStrings();
for (String s : reversed(someStrings)) {
    doSomethingWith(s);
}

22
এটিই মূলত গুগলের আইটিবেলস.রিভার্স যা করে, হ্যাঁ :)
জন স্কিটি

10
আমি জানি একটি 'নিয়ম' আছে যা আমাদের জনের জবাব মেনে নিতে হবে :) তবে .. আমি এইটি গ্রহণ করতে চাই (যদিও তারা মূলত একই রকম) যদিও আমাকে অন্য একটি তৃতীয় পক্ষের লাইব্রেরি অন্তর্ভুক্ত করার দরকার নেই (যদিও কেউ কেউ যুক্তি দিতে পারে যে সেই কারণেই ওওর অন্যতম প্রধান সুবিধা - পুনরায় ব্যবহারযোগ্যতা)।
রন টফিন

ছোট ত্রুটি: সর্বজনীন শূন্যতা অপসারণ () এ, কোনও রিটার্ন বিবৃতি থাকা উচিত নয়, এটি ঠিক হওয়া উচিত: i.remove ();
জেস্পার

10
কালেকশনস.রেভারস () বিপরীত অনুলিপিটি ফেরত দেয় না তবে পরামিতি হিসাবে লিস্ট করা তালিকায় কাজ করে। যদিও আপনার পুনরাবৃত্তির সাথে সমাধানটি পছন্দ করুন। সত্যিই মার্জিত।
er4z0r

96

একটি তালিকার জন্য, আপনি গুগল পেয়ারা লাইব্রেরি ব্যবহার করতে পারেন :

for (String item : Lists.reverse(stringList))
{
    // ...
}

দ্রষ্টব্য যে পুরো সংগ্রহটি বিপরীত করে না বা এর মতো কিছু করে - এটি কেবল বিবর্তন ক্রমে পুনরাবৃত্তি এবং এলোমেলো অ্যাক্সেসের অনুমতি দেয়। প্রথমে সংগ্রহটি উল্টানোর চেয়ে এটি আরও দক্ষ।Lists.reverse

একটি নির্বিচারে পুনরাবৃত্তীয় বিপরীত করতে, আপনি এটি সব পড়তে হবে এবং তারপরে এটি "পুনরায় খেলতে" হবে "

(আপনি যদি ইতিমধ্যে এটি ব্যবহার না করেন তবে আমি পেয়ারার দিকে একবার নজর রাখার জন্য পুরোপুরি পরামর্শ দিচ্ছি It's এটি দুর্দান্ত জিনিস))


1
আমাদের কোডবেস লারওয়ালাবস দ্বারা প্রকাশিত কমন্স সংগ্রহের জেনারাইড সংস্করণ ( লারওয়াল্যাবস / সংগ্রহ ) ভারী ব্যবহার করে । অ্যাপাচি কমন্সের জন্য এসভিএন রেপোটি দেখে, এটা পরিষ্কার যে কমন্স কালেকশনের জাভা 5 সংস্করণ প্রকাশের বেশিরভাগ কাজ শেষ হয়েছে, তারা এখনও এটি প্রকাশ করেনি।
স্কাফম্যান

আমি এটা পছন্দ করি. যদি এটি এতটা কার্যকর না হত তবে আমি এটিকে একটি প্লাগ কল করব।
geowa4

আমি অবাক হয়েছি কেন জাকার্তা কখনই অ্যাপাচি কমন্স আপডেট করতে বিরত হন না।
উরি

3
তারা এটি আপডেট করেছে, আমি এটাই বলছি। তারা কেবল এটি প্রকাশ করেনি।
স্ক্যাফম্যান

23
Iterables.revers অবচিত করা হয়েছে, পরিবর্তে Lists.revers বা ImmutableList.revers ব্যবহার করুন।
গ্যারেট হল

39

তালিকাটি (সেটটির বিপরীতে) একটি অর্ডার করা সংগ্রহ এবং এর উপরে পুনরাবৃত্তি চুক্তির মাধ্যমে অর্ডার সংরক্ষণ করে না। আমি বিপরীত ক্রমে পুনরুক্তি করার জন্য একটি স্ট্যাকের আশা করতাম তবে দুর্ভাগ্যক্রমে এটি হয় না। সুতরাং আমি যে সহজ সমাধানটি ভাবতে পারি তা হ'ল:

for (int i = stack.size() - 1; i >= 0; i--) {
    System.out.println(stack.get(i));
}

আমি বুঝতে পারি যে এটি একটি "প্রতিটি" লুপ সমাধান নয়। আমি গুগল সংগ্রহের মতো নতুন লাইব্রেরি প্রবর্তনের চেয়ে লুপের জন্য ব্যবহার করব।

কালেকশনস.রেভারস () এছাড়াও কাজটি করে তবে বিপরীত ক্রমে একটি অনুলিপি ফেরানোর বিপরীতে তালিকাটি আপডেট করে।


3
এই পদ্ধতির অ্যারে ভিত্তিক তালিকার জন্য সূক্ষ্ম হতে পারে (যেমন অ্যারেলিস্ট) তবে লিঙ্কযুক্ত তালিকার পক্ষে এটি সর্বোত্তম হবে কারণ প্রতিটি প্রাপ্তির জন্য প্রতিটি প্রাপ্তির জন্য শুরু থেকে শেষ (অথবা সম্ভবত শেষের দিকে) তালিকাটি অতিক্রম করতে হবে। নাট এর দ্রবণ হিসাবে (তালিকার সমস্ত বাস্তবায়নের জন্য অনুকূল) হিসাবে স্মার্ট ইটারেটর ব্যবহার করা ভাল।
ক্রিস

1
আরও, এটি ওপিতে অনুরোধ থেকে বিরত থাকে যা স্পষ্টভাবে for eachবাক্য গঠনের জন্য জিজ্ঞাসা করে
পল ডব্লিউ

8

এটি আসল তালিকার সাথে জগাখিচুড়ি করবে এবং লুপের বাইরেও কল করা দরকার। এছাড়াও আপনি যখন লুপ করবেন প্রতিবার বিপরীত সম্পাদন করতে চান না - যদি Iterables.reverse ideasকোনওটির প্রয়োগ হয় তবে তা কি সত্য হবে ?

Collections.reverse(stringList);

for(String string: stringList){
//...do something
}

5

এএফআইকে স্ট্যান্ডার্ড লাইব্রেরিতে এমন কোনও স্ট্যান্ডার্ড "রিভার্স_াইটেটেরেটর" ধরণের জিনিস নেই যা প্রতিটা সিনট্যাক্সকে সমর্থন করে যা ইতিমধ্যে একটি সিনট্যাকটিক চিনি যা তারা ভাষায় দেরীতে এনেছিল।

আপনি এর জন্য (আইটেম উপাদান: myList.clone ()। বিপরীত ()) এর মতো কিছু করতে পারেন এবং সম্পর্কিত মূল্যটি প্রদান করতে পারেন।

এটি আপনাকে ব্যয়বহুল ক্রিয়াকলাপগুলি করার সুবিধাজনক উপায়গুলি না দেওয়ার আপাত ঘটনার সাথে মোটামুটি সামঞ্জস্যপূর্ণ বলে মনে হয় - যেহেতু একটি তালিকা সংজ্ঞা অনুসারে ও (এন) এর এলোমেলো অ্যাক্সেস জটিলতা থাকতে পারে (আপনি একটি একক লিঙ্কের সাথে ইন্টারফেসটি প্রয়োগ করতে পারেন), বিপরীত পুনরাবৃত্তিটি ও (এন ^ 2) হয়ে শেষ হতে পারে। অবশ্যই আপনার যদি অ্যারেলিস্ট থাকে তবে আপনি সেই দামটি দেবেন না।


আপনি পিছনে পিছনে একটি তালিকার তালিকা চালাতে পারেন, যা কোনও আইট্রেটারের মধ্যে গুটিয়ে রাখা যেতে পারে।
টম হাটিন -

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

ডেকের একটি বিপরীত পুনরুক্তি রয়েছে।
মাইকেল মুন্সে

2

এটি একটি বিকল্প হতে পারে। আশা করি শেষের দিকে লুপ করার চেয়ে শেষ উপাদান থেকে শুরু করার আরও ভাল উপায় আছে।

public static void main(String[] args) {        
    List<String> a = new ArrayList<String>();
    a.add("1");a.add("2");a.add("3");a.add("4");a.add("5");

    ListIterator<String> aIter=a.listIterator();        
    while(aIter.hasNext()) aIter.next();

    for (;aIter.hasPrevious();)
    {
        String aVal = aIter.previous();
        System.out.println(aVal);           
    }
}

2

মন্তব্য হিসাবে : আপনার অ্যাপাচি কমন্স ব্যবহার করা উচিত ableReverseListIterator

Iterable<String> reverse 
    = new IteratorIterable(new ReverseListIterator(stringList));

for(String string: reverse ){
    //...do something
}

@ আরগারডপ্যাক যেমন বলেছে , আপনার এটিরReverseListIterator মতো একটি মোড়ানো দরকার Iterable


1

কিছু কাস্টম কোড না লিখেই নয় যা আপনাকে এমন একটি পরিগণক দেবে যা আপনার জন্য উপাদানগুলিকে বিপরীতমুখী করবে।

আপনার জাভাতে এটিতে সক্ষম হতে হবে ইটারেবলের একটি কাস্টম বাস্তবায়ন তৈরি করে যা উপাদানগুলিকে বিপরীত ক্রমে ফিরিয়ে দেয়।

তারপরে, আপনি মোড়কটি ইনস্ট্যান্ট করবেন (বা পদ্ধতিটি কল করুন, আপনাকে কী আছে) যা প্রত্যাখ্যানযোগ্য বাস্তবায়ন ফিরিয়ে দেবে যা প্রতিটি লুপের জন্য উপাদানটিকে বিপরীত করে।



1

আপনি যদি বাক্সের বাইরে প্রতিটি সিনট্যাক্সের জন্য ব্যবহার করতে চান এবং বিপরীত ক্রমে যেতে চান তবে আপনার সংগ্রহটি বিপরীত করতে হবে।


1

উপরের সমস্ত উত্তরগুলি কেবলমাত্র অন্য পদ্ধতিটি মোড়ানো বা বাইরে কিছু বিদেশী কোড কল করে প্রয়োজনীয়তা পূরণ করে;

থাইঙ্কিং ইন জাভা চতুর্থ সংস্করণ , অধ্যায় 11.13.1 অধ্যায় অ্যাডাপ্টারমেথোডিয়াম থেকে অনুলিপি করা সমাধানটি এখানে রয়েছে ;

কোডটি এখানে:

// The "Adapter Method" idiom allows you to use foreach
// with additional kinds of Iterables.
package holding;
import java.util.*;

@SuppressWarnings("serial")
class ReversibleArrayList<T> extends ArrayList<T> {
  public ReversibleArrayList(Collection<T> c) { super(c); }
  public Iterable<T> reversed() {
    return new Iterable<T>() {
      public Iterator<T> iterator() {
        return new Iterator<T>() {
          int current = size() - 1; //why this.size() or super.size() wrong?
          public boolean hasNext() { return current > -1; }
          public T next() { return get(current--); }
          public void remove() { // Not implemented
            throw new UnsupportedOperationException();
          }
        };
      }
    };
  }
}   

public class AdapterMethodIdiom {
  public static void main(String[] args) {
    ReversibleArrayList<String> ral =
      new ReversibleArrayList<String>(
        Arrays.asList("To be or not to be".split(" ")));
    // Grabs the ordinary iterator via iterator():
    for(String s : ral)
      System.out.print(s + " ");
    System.out.println();
    // Hand it the Iterable of your choice
    for(String s : ral.reversed())
      System.out.print(s + " ");
  }
} /* Output:
To be or not to be
be to not or be To
*///:~

int current = size() - 1সঠিক কেন ? কেন int current = this.size() - 1বাint current = super.size() - 1
কিউইন লি


0

এই প্রশ্নের অবশ্যই একটি দেরী উত্তর। লুপের জন্য একটি তালিকাতে তালিকাগুলি ব্যবহার করা একটি সম্ভাবনা। এটি কোলন-সিনট্যাক্সের মতো পরিষ্কার নয়, তবে এটি কাজ করে।

List<String> exampleList = new ArrayList<>();
exampleList.add("One");
exampleList.add("Two");
exampleList.add("Three");

//Forward iteration
for (String currentString : exampleList) {
    System.out.println(currentString); 
}

//Reverse iteration
for (ListIterator<String> itr = exampleList.listIterator(exampleList.size()); itr.hasPrevious(); /*no-op*/ ) {
    String currentString = itr.previous();
    System.out.println(currentString); 
}

তালিকাসমূহের সিনট্যাক্সের জন্য ক্রেডিট "জাভাতে কোনও তালিকাতে পুনরাবৃত্তি করার উপায়গুলি" তে যায়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.