আসসালামুলাইকুম, সবাইকে শুভেচ্ছা জানিয়ে শুরু করছি আমার ধারাবাহিক টিউনের ৯ম পর্ব। আজকের পর্বে আমরা শিখবঃ
যারা পূর্বে C/C++ এর জেনেরিক ক্লাস নিয়ে কাজ করেছেন তাদের জন্য এই টিউন বুঝতে অনেক সহজ হবে। তবে আমি চেষ্টা করছি সবার সুবিধার্থে বিস্তারিত ভাবে লিখতে। এর পরেও কারোর বুঝতে অসুবিধা হলে আমি দুঃখীত। কমেন্টে আপনার সমস্যার কথা উল্লেখ করুন, যদি সীমিত জ্ঞ্যানের মধ্যে পারি তাহলে সমাধান দিতে পারব ইনশাআল্লাহ।
কালেকশন হল কিছু পূর্ব নির্ধারিত কালেকশন স্ট্রাকচার যা বিভিন্ন টাইপের অবজেক্ট ধারন করে (অনেকটা লিস্ট এর মত) এবং প্রয়োজন অনুসারে ডাটা বার করে আনা যায় বা নতুন কোন ডাটা ইনসার্ট করা হয়। সকল প্রোগ্রামিং ল্যাঙ্গুয়েজে জেনেরিক কালেকশন একটি গুরুত্বপূর্ণ কালেকশন স্ট্রাকচার যা প্রফেশনাল প্রোগ্রামার দের অনেক কাজ সহজ করে দেয়। যাইহোক, সি শার্পে অনেক নতুন জেনেরিক কালেকশন ব্যবহারের সুযোগ হয়েছে। জেনেরিক কালেকশন আর নন-জেনেরিক কালেকশনের মধ্যে তেমন কোন পার্থক্য না থাকলেও একমাত্র পার্থক্য যেটা রয়েছে সেটা হলঃ জেনেরিক কালেকশন একটি মাত্র নির্দিষ্ট ডাটা টাইপের জন্য একটি পৃথক কালেকশন স্ট্রাকচার ব্যবহার করে, অর্থাৎ সকল ধরনের ডাটা একসাথে রাখা হয়না। অন্যদিকে নন-জেনেরিক কালেকশন অবজেক্ট টাইপ নিয়ে কাজ করে এবং সকল ডাটা কে একসাথে অবজেক্টে রুপান্তর করে রাখে।
জেনেরিক কালেকশন ব্যবহারের জন্য ব্যবহৃত নেমস্পেসঃ System.Collections.Generic
নন-জেনেরিক কালেকশন ব্যবহারের জন্য ব্যবহৃত নেমস্পেসঃ System.Collections
এই দুইটি নেমস্পেস কোডিং এর শুরুতেই ইম্পোর্ট করে নিতে হবে (যদি করা না থাকে) এভাবেঃ
using System.Collections
using System.Collections.Generic
কালেকশন কেন ব্যবহার করব তা ছোট উদাহরণ দিয়ে বুঝিয়ে দেই। ধরুন আপনাকে এমন প্রোগ্রাম তৈরী করতে বলা হল যেখানে প্রয়োজন মত ডাটা কালেকশন Stack/Queue structure ব্যবহার করার দরকার হয় (Database ব্যবহার করার সুযোগ নেই) , তাহলে আপনি সহজেই সেই স্ট্রাকচার কালেকশন থেকে কল (Call) করতে পারবেন। আর যদি সে সুযোগ না থাকত তাহলে আপনাকে সম্পূর্ণ ম্যানুয়ালি এমন স্ট্রাকচার প্রোগ্রামিং করে বানিয়ে নিতে হবে যা অনেক সময়সাধ্য ও কঠিন। যারা CSE এর স্টুডেন্ট আছেন/ছিলেন তারা হয়ত মনে করতে পারবেন যে ভার্সিটির প্রোগ্রামিং অনলাইন সেশনাল এ কত কষ্ট করে এই সকল কালেকশন স্ট্রাকচার (Stack, Queue, Linked List etc.) হাতে কলমে C/C++ দিয়ে ইমপ্লিমেন্ট করেছিলেন। আমার এখনো মনে আছে 2-1 এ C++ দিয়ে লিঙ্ক লিস্ট ইমপ্লিমেন্ট করার সময় স্যারকে জিজ্ঞেস করেছিলাম বোকার মতঃ “স্যার, কালেকশন ইউজ করা যাবে না?” স্যার আমার এরূপ আবদার শুনে বললেন “তাহলে, আমার ক্লাসে থাকতে পারবে না”
যাইহোক, এসকল কথা বলার লক্ষ ছিল আপনাদেরকে কালেকশনের উপকারিতা বোঝানো-আর কিছুই না। আশা করি বুঝতে সক্ষম হয়েছেন।
.NET Framework এ বিভিন্ন ধরনের কালেকশন ব্যবহার করা হয়। যেমনঃ
ArrayList ডট নেট ১.০ থেকে ছিল এবং লিস্ট এর পূর্বসূরী। এই কালেকশন শুধু মাত্র অবজেক্ট নিয়ে কাজ করতে পারে। অর্থাৎ এই কালেকশনে যে ধরনের ডাটা রাখুন না কেন, তা অবশ্যই অবজেক্ট হিসেবে রাখতে হবে।
সমস্যাঃ
প্রথমতঃ একি লিস্টে বিভিন্ন ধরনের ডাটা থাকতে পারে (যেহেতু সব ডাটাকে অবজেক্ট হিসেবে রাখা হয়)। একারনে একি ফাংশন দিয়ে বিভিন্ন ধরনের ডাটা ম্যানিপুলেট করা সম্ভব নয়। যেমনঃ আপনার ArrayList এ যদি integer, string, image type এর ডাটা থেকে থাকে, তাহলে ডাটা বের করে আনার সময় আপনাকে তিন ধরনের ডাটা টাইপের জন্য তিনটি ভিন্ন পদ্ধতিতে ডাটা বার করতে হবে।
দ্বিতীয়তঃ বিভিন্ন ধরনের ডাটাকে অবজেক্টে রুপান্তর করে রাখা এবং পুনরায় অবজেক্ট থেকে পূর্বের অবস্থায় নিয়ে তা দেখানো, এসবের জন্য অতিরিক্ত কখনো কঠিন ম্যানিপুলেশন দরকার হয়।
তৃতীয়তঃ অন্যান্য কালেকশন থেকে ArrayList অনেক ধীরগতি সম্পন্ন।
এই কালেকশন এ প্রত্যেক ডাটা অবজেক্ট Key/Value জোড়ায় রাখা হয়। অর্থাৎ প্রত্যেক ডাটা অবজেক্ট রেকর্ডের জন্য দুইটি এট্রিবিউট Key/Value থাকে। এটি একটি নন-জেনেরিক কালেকশন বলেই বিভিন্ন ডাটা টাইপের রেকর্ডের জন্য একটি মাত্র কালেকশন ব্যবহার করা হয়। এই কালেকশনের সমস্যা পূর্বের ArrayList এর মতই।
সাধারনতঃ স্ট্যাক বলতে কোন কিছুর স্তুপ বোঝানো হয়। কম্পিউটার সাইন্সে স্ট্যাক বলতে এমন একটি কালেকশন স্ট্রাকচারকে বোঝানো হয়, যেখানে LIFO (Last-In First-Out) অর্ডার মেনে চলা হয়। উদাহরণ হিসেবে মনে করুন আপনার ডাইনিং টেবিলে একটি একটি করে প্লেট রাখছেন, অর্থাৎ, প্রথমে একটি প্লেট রেখে তার উপর আরেকটি এর উপর আর-একটি এভাবে ১০ টি প্লেট রাখলেন। এখন প্রথমে যে প্লেট টি রেখেছিলেন সেটি সবার নিচে থাকবে এবং ১০ম প্লেট (শেষ) টি সবার উপরে থাকায়, যদি কোন প্লেট সরাতে চান তাহলে শেষ প্লেট সবার আগে সরবে, এর পর তার আগে যে প্লেট ছিল সেটি সরবে এভাবে সবার শেষে প্রথমে যে প্লেট টি রেখেছেন সেটি সরবে। এই কারনে একে LIFO (Last-In First-Out) বলা হয়। এই কালেকশন স্ট্রাকচার এই ধরনের অর্ডার মেনে চলে। তবে স্বাভাবিক ভাবেই নন-জেনেরিক হওয়ায় এটি সব ধরনের ডাটা অবজেক্ট নিয়ে কাজ করে।
এই কালেকশন স্ট্রাকচার FIFO (First-In First-Out) অর্ডার মেনে চলে। অর্থাৎ সবার প্রথমে যে আসবে সে সবার আগেই বার হবে। অনেকটা বাসের লাইনের মত। যে সবার আগে এসেছেন সে সবার আগে বাসে প্রবেশ করবেন।
List<T> বিশেষ ধরনের লিস্ট যা অনেকটা আগেরটির মতই কাজ করে তবে ArrayList এর থেকে পার্থক্য হলঃ List<T> আপনার পছন্দ মত যে কোন ডাটা টাইপ নিয়ে কাজ করে। অর্থাৎ, প্রত্যেকটি ডাটা টাইপের জন্য আলাদা আলাদা লিস্ট রাখা হয়। List<T> তে T দিয়ে ডাটা টাইপ কে বোঝানো হয়-যেমনঃ যদি ইন্টিজার টাইপের ডাটা রাখার জন্য লিস্ট তৈরী করেন, তাহলে, List<int> এভাবে লিখতে হবে। এর অন্যতম সুবিধা হল একি ডাটা টাইপ একসাথে থাকে বলে ম্যানিপুলেশনের সময় কোন সমস্যা হয়না।
Add
AddRange
Contains
CopyTo
IndexOf
Find
Sort
Reverse ইত্যাদি।
এই কালেকশনে যে কোন ডাটা কি (Key) এবং ভ্যালু (Value) জোড়ায় রাখা হয়। অর্থাৎ প্রত্যেক ডাটা রেকর্ডের জন্য দুইটি এট্রিবিউট সংরক্ষণ করা হয়। এটি Hashtable এর মত কাজ করে তবে পার্থক্য হল এটি জেনেরিক কালেকশন অর্থাৎ একটি কালেকশনে কেবল মাত্র একটি নির্দিষ্ট ডাটা টাইপের রেকর্ড রাখতে পারে। পরবর্তিতে বিস্তারিত বলা হবে।
এখানে বিশেষ কিছু বলার নেই কারণ Stack<T> হল নন-জেনেরিক Stack এর জেনেরিক রূপ। অর্থাৎ একটি নির্দিষ্ট ডাটা টাইপ নিয়ে কাজ করে। T এর স্থলে যেকোন ডাটা টাইপ লিখতে হবে।
এটিও অনুরূপ ভাবে নন-জেনেরিক Queue এর জেনেরিক রূপ। T এর স্থলে যেকোন ডাটা টাইপ লিখতে হবে।
উপরের প্রোগ্রামে লক্ষ করুন, একটি integer type এর List object li নেয়া হয়েছে। এরপর Add function এর মাধ্যমে তিনটি ভিন্ন ইন্টিজার আইটেম যুক্ত করা হয়েছে। এরপর কন্সোল আউটপুটে লিস্টের আইটেম সংখ্যা দেখানো হয়েছে li.Count ব্যবহার করে (যেহেতু এটি int রিটার্ন করে যা কন্সোল আউটপুট সাপোর্ট করেনা তাই ToString() এর মাধ্যমে String এ কনভার্ট করা হয়েছে)
এরপর foreach loop এর মাধ্যমে প্রত্যেকটি আইটেম কে কন্সোল আউটপুটে দেখানো হয়েছে।
এখানে for loop এর মধ্যে প্রত্যেকবার নাম ইনপুট নেয়া হচ্ছে এবং লিস্টে রাখা হচ্ছে। যেহেতু লিস্ট এর কোন ক্যাপাসিটি ঠিক করে দেয়া নাই। তাই এটি অসংখ্যবার নাম ইনপুট নিতে পারবে (প্রোগ্রামের শর্তয়ানুযায়ী যতক্ষন পর্যন্ত end ইনপুট দেয়া না হয়)। end ইনপুট পাওয়া সাপেক্ষে লিস্টের শেষে EOL Add করা হয়েছে। আশা করি বুঝতে পারছেন।
এখানে list input হিসেবে দিলে লিস্টের সকল ইনপুট দেয়া তথ্য (যা পূর্বে দিয়েছেন) দেখাবে। এখানেও foreach লুপের মাধ্যমে লিস্টের শেষ আইটেম পর্যন্ত (যতক্ষন EOL না পায়) কন্সোলে আউটপুট দেখানো হয়েছে। এখানে ইন্ডেক্স দেখানোর জন্য IndexOf(string item) function ব্যবহার করা হয়েছে।
এখানে দুইটি এট্রিবিউট Key/Value pair ব্যবহার করা হয়। প্রথমেই, key/value pair এর জন্য টাইপ ঘোষণা দিতে হয়। নিচের প্রোগ্রাম দেখুনঃ
একটি Dictionary<int,string> object dc নেয়া হয়েছে যার key এর ডাটা টাইপ int এবং value এর ডাটা টাইপ string। এরপর তিনটি আইটেম যুক্ত করা হয়েছে (Item 1, Item 2, Item 3 যাদের key যথাক্রমে 1,2,3)
এরপর foreach লুপে KeyValuePair<int,string> এর একটি অবজেক্ট নেয়া হয়েছে যা Dictionary element এর key/value pair ধারন করবে। এরপর সেটা কন্সোলে আউটপুট দেখানো হয়েছে।
আশা করি কালেকশন সম্পর্কে আপনারা ধারণা পেয়েছেন। আমি এখানে সময় স্বল্পতার কারনে দুইটি গুরুত্বপূর্ণ জেনেরিক কালেকশন List<T> ও Dictionary<TKey,TValue> নিয়ে আলোচনা করেছি। আশা করি বাকি কালেকশন (জেনেরিক ও নন-জেনেরিক উভয়) খুব ভাল করে বুঝতে পারবেন যখন নিজে কাজ করবেন।
আমি চিন্তা করেছি, আমার ধারাবাহিক টিউনের শেষে পর্যায়ক্রমে গুরুত্বপূর্ণ প্রোগ্রামগুলো কোনো সাইটে আপলোড করে দিব। আপনাদের অভিমত কি?
সবশেষে এটুকু বলব, আমার মায়ের জন্য একটু দোয়া করবেন। আজকে কিছুক্ষন আগে তার চোখের নিচের টিউমারের অপারেশন শেষ হল। মহান আল্লাহ'র কৃপায় ভালই আছেন তবে কিছুটা দুর্বল।
আমি জ্যোতি। বিশ্বের সর্ববৃহৎ বিজ্ঞান ও প্রযুক্তির সৌশল নেটওয়ার্ক - টেকটিউনস এ আমি 13 বছর 10 মাস যাবৎ যুক্ত আছি। টেকটিউনস আমি এ পর্যন্ত 17 টি টিউন ও 98 টি টিউমেন্ট করেছি। টেকটিউনসে আমার 2 ফলোয়ার আছে এবং আমি টেকটিউনসে 0 টিউনারকে ফলো করি।
আমি জ্যোতি চৌধুরী। কম্পিউটার সাইন্স এন্ড ইঞ্জিনিয়ারিং এর ছাত্র। মিলিটারি ইন্সটিটিউট অফ সাইন্স এন্ড টেকনোলজি, মিরপুর ক্যান্টনমেন্ট এ পড়াশোনা করছি। ভাল লাগে বন্ধুদের সাথে আড্ডা দিতে, কম্পিউটার প্রযুক্তি সম্পর্কে জানতে। আগ্রহ আছে সফটওয়্যার ডেভেলপমেন্ট, প্রোগ্রামিং ও ওয়েব ডেভেলপমেন্টের প্রতি। স্বপ্ন দেখতে ভালবাসি। স্বপ্ন কে বাস্তবে রুপায়ন করতে পছন্দ করি।
Khub e valo hoy. U R really doing a nice job 🙂