"হাই, অ্যামিগো!"

"হাই, এলি!"

"আজ আমি আপনাকে পুনরাবৃত্তিকারীদের সম্পর্কে বলতে চাই।"

"ইটারেটরগুলি কার্যত সংগ্রহের মতো একই সময়ে উদ্ভাবিত হয়েছিল৷ সংগ্রহের মূল উদ্দেশ্য উপাদানগুলি সংরক্ষণ করা, এবং একটি পুনরাবৃত্তিকারীর মূল উদ্দেশ্য হল এই উপাদানগুলিকে একের পর এক পুনরুদ্ধার করা।"

"উপাদানের একটি সেট পেতে এত কঠিন কি?"

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

"দ্বিতীয়, কিছু ডেটা স্ট্রাকচার বস্তুগুলিকে খুব জটিল উপায়ে সংরক্ষণ করতে পারে: বিভিন্ন গোষ্ঠী, তালিকা ইত্যাদিতে। অন্য কথায়, সমস্ত উপাদানগুলিকে ক্রমানুসারে হস্তান্তর করা একটি অ-তুচ্ছ কাজ হবে।"

"তৃতীয়ত, সংগ্রহগুলি পরিবর্তিত হতে থাকে। ধরুন আপনি একটি সংগ্রহের সম্পূর্ণ বিষয়বস্তু প্রদর্শন করার সিদ্ধান্ত নিয়েছেন, কিন্তু আউটপুটের ঠিক মাঝখানে JVM অন্য থ্রেডে স্যুইচ করে যা সংগ্রহের উপাদানগুলির অর্ধেক প্রতিস্থাপন করে। সুতরাং আউটপুটের পরিবর্তে, আপনি পাবেন কে কি জানে।"

"হুম..."

"কিন্তু! এগুলি সঠিকভাবে এমন ধরণের সমস্যা যা একজন পুনরাবৃত্তিকারী সমাধান করতে পারে৷ একটি পুনরাবৃত্তিকারী একটি সংগ্রহের মধ্যে একটি বিশেষ বস্তু যা, একদিকে, তার সমস্ত ব্যক্তিগত ডেটা অ্যাক্সেস করতে পারে এবং এটির অভ্যন্তরীণ কাঠামো জানে এবং অন্যদিকে , পাবলিক ইটারেটর ইন্টারফেস প্রয়োগ করে, যা প্রত্যেককে এটির সাথে কীভাবে কাজ করতে হয় তা জানতে দেয়। "

"কিছু পুনরাবৃত্তের একটি অভ্যন্তরীণ অ্যারে থাকে যার মধ্যে সংগ্রহের সমস্ত উপাদান অনুলিপি করা হয় যখন পুনরাবৃত্তিকারী তৈরি করা হয়। এটি নিশ্চিত করে যে সংগ্রহের পরবর্তী পরিবর্তনগুলি উপাদানগুলির সংখ্যা বা ক্রমকে প্রভাবিত করবে না।"

"আমি মনে করি আপনি প্রতিটির জন্য কাজ করার সময় এটি জুড়ে এসেছেন । আপনি একই সাথে একটি সংগ্রহের উপর লুপ করতে পারবেন না এবং এটি থেকে উপাদানগুলি সরিয়ে ফেলতে পারবেন না। এটি একটি ইটারেটর যেভাবে কাজ করে তার কারণেই এটি হয়।"

"কনকারেন্সি লাইব্রেরিতে যোগ করা নতুন সংগ্রহগুলিতে, এই সমস্যাটি দূর করার জন্য পুনরাবৃত্তিকারীকে পুনরায় কাজ করা হয়েছে।"

"আমাকে আপনাকে মনে করিয়ে দিই কিভাবে একটি পুনরাবৃত্তিকারী কাজ করে।"

"জাভার একটি বিশেষ ইটারেটর ইন্টারফেস রয়েছে। এখানে এর পদ্ধতিগুলি রয়েছে:"

Iterator<E> ইন্টারফেসের পদ্ধতি বর্ণনা
boolean hasNext() আরো কোনো উপাদান আছে কিনা চেক করুন
E next() বর্তমান উপাদান ফেরত দেয় এবং পরবর্তীতে চলে যায়।
void remove() বর্তমান উপাদান সরিয়ে দেয়

"একটি পুনরাবৃত্তিকারী আপনাকে ক্রমাগতভাবে একটি সংগ্রহের সমস্ত উপাদান পেতে দেয়৷ একটি পুনরাবৃত্তকে একটি ইনপুটস্ট্রিমের মতো কিছু হিসাবে ভাবা আরও যৌক্তিক - এতে সমস্ত ডেটা রয়েছে, তবে এর কাজ হল এটিকে ক্রমানুসারে আউটপুট করা।"

"   পরবর্তী () পদ্ধতি সংগ্রহের পরবর্তী উপাদান প্রদান করে।"

" আর কোন উপাদান আছে কিনা তা পরীক্ষা করতে hasNext () পদ্ধতি ব্যবহার করা হয়।"

"এবং remove () বর্তমান উপাদানটিকে সরিয়ে দেয়।"

"কোন প্রশ্ন?"

"কেন পদ্ধতির এমন অদ্ভুত নাম আছে? কেন isEmpty() এবং getNextElement() নয়?"

"এটা কি আরও অর্থপূর্ণ হবে না?"

"এটি আরও বোধগম্য হবে, তবে নামগুলি C++ ভাষা থেকে এসেছে, যেখানে পুনরাবৃত্তিকারীরা আগে উপস্থিত হয়েছিল।"

"আমি দেখছি। চলুন চালিয়ে যাই।"

"একটি ইটারেটর ছাড়াও, ইটারেবল ইন্টারফেসও রয়েছে, যা পুনরাবৃত্তিকারীকে সমর্থন করে এমন সমস্ত সংগ্রহ দ্বারা প্রয়োগ করা আবশ্যক। এটির একটি একক পদ্ধতি রয়েছে:"

পুনরাবৃত্তিযোগ্য<T> ইন্টারফেসের পদ্ধতি বর্ণনা
Iterator<T>iterator() একটি পুনরাবৃত্তিকারী বস্তু প্রদান করে

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

উদাহরণ
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}

"এই ধরনের একটি ইটারেটর ব্যবহার করা খুব সুবিধাজনক নয় - খুব বেশি অতিরিক্ত এবং সুস্পষ্ট কোড আছে। পরিস্থিতি আরও সহজ হয়ে ওঠে যখন জাভাতে প্রতিটি লুপ উপস্থিত হয়।"

"এখন এই কোডটি অনেক বেশি কম্প্যাক্ট এবং পঠনযোগ্য:"

আগে পরে
TreeSet<String> set = new TreeSet<String>();
Iterator<String> iterator = set.iterator();

while (iterator.hasNext())
{
 String item = iterator.next();
 System.out.println(item);
}
TreeSet<String> set = new TreeSet<String>();

for(String item : set)
{
 System.out.println(item);
}

"এটি একই কোড! উভয় ক্ষেত্রেই পুনরাবৃত্তিকারী ব্যবহার করা হয়।"

" প্রত্যেকটি লুপে এর ব্যবহার লুকানো আছে । মনে রাখবেন যে ডানদিকের কোডটিতে কোনো লাল লেখা নেই। ইটারেটরের ব্যবহার সম্পূর্ণ লুকানো আছে।"

" যেকোন অবজেক্টের জন্য একটি লুপ ব্যবহার করা হবে যা ইটারেটরকে সমর্থন করে। অন্য কথায়, আপনি নিজের ক্লাস লিখতে পারেন, এটিতে ইটারেটর () মেথড যোগ করতে পারেন এবং এর অবজেক্টগুলিকে প্রতিটি নির্মাণের জন্য ব্যবহার করতে পারেন।"

"বাহ! অবশ্যই, আমি আমার নিজের সংগ্রহ এবং পুনরাবৃত্তিকারী লিখতে আগ্রহী নই, কিন্তু সম্ভাবনা এখনও প্রলোভনশীল। আমি এটির একটি নোট করব।"

উপরন্তু, আরেকটি জনপ্রিয় ধরনের ইটারেটর রয়েছে যার নিজস্ব ইন্টারফেসও রয়েছে। আমি তালিকার জন্য একটি পুনরাবৃত্তিকারীর কথা বলছি, যেমন ListIterator

"তাদের বাস্তবায়ন নির্বিশেষে, তালিকাগুলি উপাদানগুলির ক্রম বজায় রাখে, যা তাদের সাথে একটি পুনরাবৃত্তের মাধ্যমে আরও কিছুটা সুবিধাজনকভাবে কাজ করে।"

"এখানে ListIterator <E> ইন্টারফেসের পদ্ধতি রয়েছে :"

পদ্ধতি বর্ণনা
boolean hasNext() সামনে আরও কোনো উপাদান আছে কিনা তা পরীক্ষা করে দেখুন।
E next() পরবর্তী উপাদান প্রদান করে।
int nextIndex() পরবর্তী উপাদানের সূচী প্রদান করে
void set(E e) বর্তমান উপাদানের মান পরিবর্তন করে
boolean hasPrevious() পিছনে কোন উপাদান আছে কিনা তা পরীক্ষা করে দেখুন।
E previous() পূর্ববর্তী উপাদান প্রদান করে
int previousIndex() পূর্ববর্তী উপাদানের সূচী প্রদান করে
void remove() বর্তমান উপাদান সরিয়ে দেয়
void add(E e) তালিকার শেষে একটি উপাদান যোগ করে।

"অন্য কথায়, এখানে আমরা এগিয়ে এবং পিছনে উভয় দিকে যেতে পারি। এবং আরও কয়েকটি ছোট বৈশিষ্ট্য রয়েছে।"

"আচ্ছা, এটি আকর্ষণীয় জিনিস। এটি কোথায় ব্যবহৃত হয়?"

"ধরুন আপনি একটি লিঙ্ক করা তালিকায় পিছনে পিছনে যেতে চান। গেট অপারেশনটি বরং ধীর হবে, কিন্তু পরবর্তী() অপারেশনটি খুব দ্রুত হবে।"

"হুম। আপনি আমাকে বোঝালেন। আমি এটা মাথায় রাখব।"

"ধন্যবাদ, এলি!"