1. কিভাবে পুনরাবৃত্তিকারীরা এসেছে তার পটভূমি

আপনি ইতিমধ্যে পরিচিত HashSet. আপনি যদি সত্যিই একটি পাঠ পড়ার বাইরে এটি তদন্ত করে থাকেন, তাহলে আপনার এই প্রশ্নটি করা উচিত ছিল:

আমি কিভাবে পর্দায় সমস্ত HashSet উপাদানগুলির একটি তালিকা প্রদর্শন করব? get()সব পরে, ইন্টারফেস এবং set()পদ্ধতি নেই !

এবং HashSetএই সীমাবদ্ধতার মধ্যে একা নয়। ছাড়াও HashSet, আরও অনেক সংগ্রহ রয়েছে যা উপাদানগুলিকে সূচী দ্বারা পুনরুদ্ধার করার অনুমতি দেয় না, কারণ উপাদানগুলির কোনও সংজ্ঞায়িত ক্রম নেই।

বছরের পর বছর ধরে, প্রোগ্রামাররা গ্রাফ এবং গাছের মতো অনেক জটিল ডেটা স্ট্রাকচার আবিষ্কার করেছে। বা তালিকার তালিকা।

অনেক কন্টেইনার তাদের উপাদানের ক্রম পরিবর্তন করে যখন নতুন উপাদান যোগ করা হয় বা বিদ্যমান উপাদানগুলি সরানো হয়। উদাহরণস্বরূপ, একটি তালিকা একটি নির্দিষ্ট ক্রমে উপাদান সংরক্ষণ করে, এবং যখন একটি নতুন উপাদান যোগ করা হয়, এটি প্রায় সবসময় তালিকার মাঝখানে ঢোকানো হয়।

এবং আমরা এমন পরিস্থিতিতেও পাই যেখানে একটি ধারক রয়েছে যা উপাদানগুলি সঞ্চয় করে তবে কোনও নির্দিষ্ট ক্রমে নয়।

এখন ধরা যাক আমরা এমন একটি সংগ্রহ থেকে সমস্ত উপাদানকে একটি অ্যারে বা তালিকাতে অনুলিপি করতে চাই। আমরা সব উপাদান পেতে প্রয়োজন. আমরা উপাদানগুলির উপর যে ক্রমানুসারে পুনরাবৃত্তি করি সে বিষয়ে আমরা চিন্তা করি না - গুরুত্বপূর্ণ জিনিসটি একই উপাদানগুলির উপর একাধিকবার পুনরাবৃত্তি করা নয়। আমরা যে কিভাবে করব?


2. একটি সংগ্রহের জন্য পুনরাবৃত্তিকারী

উপরের সমস্যার সমাধান হিসাবে পুনরাবৃত্তিকারীদের প্রস্তাব করা হয়েছিল।

একটি পুনরাবৃত্ত হল একটি সংগ্রহের সাথে যুক্ত একটি বিশেষ বস্তু, যা কোনো পুনরাবৃত্তি ছাড়াই সংগ্রহের সমস্ত উপাদান অতিক্রম করতে সাহায্য করে।

আপনি যেকোনো সংগ্রহের জন্য একটি পুনরাবৃত্তিকারী পেতে নিম্নলিখিত কোড ব্যবহার করতে পারেন:

Iterator<Type> it = name.iterator();

nameসংগ্রহ ভেরিয়েবলের নাম কোথায় , Typeসংগ্রহের উপাদানগুলির ধরন, iterator()সংগ্রহের পদ্ধতিগুলির মধ্যে একটি এবং itএটি পুনরাবৃত্তিকারী পরিবর্তনশীলের নাম।

একটি পুনরাবৃত্তিকারী বস্তুর 3 টি পদ্ধতি রয়েছে:

পদ্ধতি বর্ণনা
Type next()
সংগ্রহে পরবর্তী উপাদান প্রদান করে
boolean hasNext()
এমন কোনো উপাদান আছে কি না যা এখনও অতিক্রম করা হয়নি তা পরীক্ষা করে
void remove()
সংগ্রহের বর্তমান উপাদান সরিয়ে দেয়

এই পদ্ধতিগুলি স্ক্যানার ক্লাস nextInt)এবং hasNextInt()পদ্ধতিগুলির সাথে কিছুটা সাদৃশ্যপূর্ণ।

পদ্ধতিটি next()সংগ্রহের পরবর্তী উপাদানটি প্রদান করে যেখান থেকে আমরা পুনরাবৃত্ত পেয়েছি।

পদ্ধতিটি hasNext()সংগ্রহে অতিরিক্ত উপাদান আছে কিনা তা পরীক্ষা করে যা পুনরাবৃত্তিকারী এখনও ফেরত দেয়নি।

একটি এর সমস্ত উপাদান কীভাবে প্রদর্শন করবেন তা এখানে HashSet:

কোড মন্তব্য
HashSet<String> set = new HashSet<String>();

set.add("Hello");
set.add("Hello");
set.add("Hola");
set.add("Bonjour");
set.add("Ciao");
set.add("Namaste");

Iterator<String> it = set.iterator();
while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}
উপাদান সংরক্ষণ করে এমন একটি HashSetবস্তু তৈরি করুন। আমরা ভেরিয়েবলে বিভিন্ন ভাষায় শুভেচ্ছা যোগ করি । সেটের জন্য একটি পুনরাবৃত্তিকারী বস্তু পান । যতক্ষণ এখনও উপাদান আছে পরের উপাদান পান পর্দায় উপাদান প্রদর্শন করুন String


set




set





3. For-eachলুপ

একটি পুনরাবৃত্তিকারীর প্রধান অসুবিধা হল যে আপনার কোডটি forলুপ ব্যবহার করার চেয়ে আরও জটিল হয়ে ওঠে।

তুলনা করতে, আসুন একটি forলুপ ব্যবহার করে এবং একটি পুনরাবৃত্তিকারী ব্যবহার করে একটি তালিকা প্রদর্শন করি:

পুনরাবৃত্তিকারী লুপের জন্য
ArrayList<String> list = new ArrayList<String>();

Iterator<String> it = list.iterator();
while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();

for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);
   System.out.println(str);
}

হ্যাঁ, লুপ ব্যবহার করে এর উপাদানগুলিকে অতিক্রম করা অনেক ভালো ArrayList— সবকিছুই ছোট হতে দেখা যাচ্ছে।

কিন্তু জাভা নির্মাতারা আবার আমাদের উপর কিছু চিনি ঢালা করার সিদ্ধান্ত নিয়েছে। ভাগ্যক্রমে আমাদের জন্য, এটি সিনট্যাকটিক চিনি ছিল ।

তারা জাভাকে একটি নতুন ধরনের লুপ দিয়েছে এবং এটিকে একটি for-eachলুপ বলেছে। এটি সাধারণভাবে দেখতে কেমন:

for(Type name:collection)

collectionসংগ্রহ ভেরিয়েবলের নাম কোথায় , Typeসংগ্রহের উপাদানগুলির ধরন এবং nameএটি একটি ভেরিয়েবলের নাম যা লুপের প্রতিটি পুনরাবৃত্তিতে সংগ্রহ থেকে পরবর্তী মান নেয়।

এই ধরনের লুপ একটি অন্তর্নিহিত পুনরাবৃত্তিকারী ব্যবহার করে একটি সংগ্রহের সমস্ত উপাদানের মাধ্যমে পুনরাবৃত্তি করে। এটি আসলে কিভাবে কাজ করে:

প্রতিটি লুপের জন্য কম্পাইলার কি দেখে: একটি পুনরাবৃত্তিকারী দিয়ে লুপ করুন
ArrayList<String> list = new ArrayList<String>();

for (String str: list)
{
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();
Iterator<String> it = list.iterator();

while (it.hasNext())
{
   String str = it.next();
   System.out.println(str);
}

যখন কম্পাইলার for-eachআপনার কোডে একটি লুপের সম্মুখীন হয়, তখন এটি কেবল ডানদিকের কোডের সাথে এটিকে প্রতিস্থাপন করে: এটি অন্য কোনো অনুপস্থিত মেথড কলের সাথে একটি ইটারেটর পেতে একটি কল যোগ করে।

প্রোগ্রামাররা for-eachলুপ পছন্দ করে এবং প্রায় সবসময় এটি ব্যবহার করে যখন তাদের একটি সংগ্রহের সমস্ত উপাদানের উপর পুনরাবৃত্তি করতে হয়।

এমনকি ArrayListএকটি লুপ ব্যবহার করে একটি তালিকার উপর পুনরাবৃত্তি for-eachছোট দেখায়:

প্রতিটি লুপের জন্য লুপের জন্য
ArrayList<String> list = new ArrayList<String>();

for (String str: list)
{
   System.out.println(str);
}
ArrayList<String> list = new ArrayList<String>();

for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);
   System.out.println(str);
}


4. একটি for-eachলুপে একটি উপাদান অপসারণ

লুপের for-eachএকটি ত্রুটি রয়েছে: এটি উপাদানগুলি সঠিকভাবে সরাতে পারে না। আপনি এই মত কোড লিখলে, আপনি একটি ত্রুটি পাবেন.

কোড বিঃদ্রঃ
ArrayList<String> list = new ArrayList<String>();

list.add("Hello");
list.add("Hello");
list.add("Hola");
list.add("Bonjour");
list.add("Ciao");
list.add("Namaste");

for (String str: list)
{
   if (str.equals("Hello"))
      list.remove(str);
}












অপসারণ অপারেশন একটি ত্রুটি উৎপন্ন হবে!

এটি একটি খুব সুন্দর এবং বোধগম্য কোড, কিন্তু এটি কাজ করবে না।

গুরুত্বপূর্ণ !

আপনি একটি সংকলন পরিবর্তন করতে পারবেন না যখন আপনি এটিকে একটি পুনরাবৃত্ত দিয়ে অতিক্রম করছেন৷

এই সীমাবদ্ধতা কাছাকাছি পেতে তিনটি উপায় আছে.

1. একটি ভিন্ন ধরনের লুপ ব্যবহার করুন

When traversing an ArrayList collectioni, আপনি একটি কাউন্টার ভেরিয়েবল সহ একটি সাধারণ লুপ ব্যবহার করতে পারেন ।

কোড
for (int i = 0; i < list.size(); i++)
{
   String str = list.get(i);

   if (str.equals("Hello"))
   {
      list.remove(str);
      i--; // We need to decrease i, because the remove operation shifted the elements
   }
}

HashSetযাইহোক, এই বিকল্পটি সংগ্রহ এবং HashMapসংগ্রহের জন্য উপযুক্ত নয়

2. একটি স্পষ্ট পুনরাবৃত্তিকারী ব্যবহার করুন

আপনি স্পষ্টভাবে একটি পুনরাবৃত্তিকারী ব্যবহার করতে পারেন এবং এর remove()পদ্ধতিকে কল করতে পারেন।

যে সংস্করণ কাজ করে যে সংস্করণ কাজ করে না
Iterator<String> it = set.iterator();
while (it.hasNext())
{
   String str = it.next();
   if (str.equals("Hello"))
       it.remove();
}

for
(String str: list) { if (str.equals("Hello")) list.remove(str); }

উল্লেখ্য যে আমরা remove()পদ্ধতিটিকে ইটারেটর অবজেক্টে কল করি! পুনরাবৃত্তিকারী সচেতন যে আইটেমটি সরানো হয়েছে এবং পরিস্থিতিটি সঠিকভাবে পরিচালনা করতে পারে।

3. সংগ্রহের একটি অনুলিপি ব্যবহার করুন

আপনি সংগ্রহের একটি অনুলিপি তৈরি করতে পারেন এবং তারপরে একটি for-eachলুপে অনুলিপিটি ব্যবহার করতে পারেন এবং মূল সংগ্রহ থেকে উপাদানগুলি মুছতে পারেন।

কোড বিঃদ্রঃ
ArrayList<String> listCopy = new ArrayList(list);

for (String str: listCopy)
{
   if (str.equals("Hello"))
      list.remove(str);
}
একটি সংগ্রহের একটি অনুলিপি তৈরি করা অত্যন্ত সহজ।



লুপ সংগ্রহের অনুলিপির জন্য পুনরাবৃত্তিকারী ব্যবহার করে।
উপাদান সংগ্রহ থেকে সরানো হয় list.

সংগ্রহটি বরং দ্রুত অনুলিপি করা হয়, যেহেতু উপাদানগুলি নিজেরাই নকল করা হয় না। পরিবর্তে, নতুন সংগ্রহটি পুরানো সংগ্রহে ইতিমধ্যে বিদ্যমান উপাদানগুলির উল্লেখ সঞ্চয় করে৷