পাঠ ১১: জাভা কালেকশান ফ্রেমওয়ার্ক
# পাঠ ১১: জাভা কালেকশান ফ্রেমওয়ার্ক
জাভা কালেকশান ফ্রেমওয়ার ভুমিকা
কালেকশান ইন্টারফেইস
লিস্ট
সর্টেট লিস্ট
ম্যাপ
সর্টেট ম্যাপ
নেভিগেবল ম্যাপ
সেট
সর্টেট সেট
নেভিগেবল সেট
Queue এবং Deque
স্ট্যাক
hashCode() এবং equals()
সারসংক্ষেপ
কালেকশান ফ্রেমওয়ার্ক
কালেকশন ফ্রেমওয়ার্ক জাভার টপ লেভের একটি এপিআই কনসেপ্ট । কালেকশান ফ্রেমওয়ার্ক কিছু হাইলি অপটিমাইজড ডাটা স্ট্রাকচার যার মাধ্যমে বিভিন্ন ডাটা মেমোরিতে স্টোর করতে পারি এবং প্রয়োজন মত ব্যাবহার করতে পারি । মনে করুন অ্যারে নিয়ে কাজ করছেন । কোন একটি সময়ে মনে হল আপনার অ্যারের সাইজ যথেষ্ঠ নয় আপনার কাজের জন্য তখন কি করবেন ? মনে করুন আপনি লিংকড লিস্ট নিয়ে কাজ করছেন কোন একটা সময়ে একটা এলিমেন্ট সার্চ করার প্রয়োজন হলো , সার্চ করলেন । দেখা গেল অনেক্ষন পর রেজাল্ট জানালো যে সেই এলিমেন্ট ওই লিস্টেই নাই । এরকম নানা রকম সমস্যা এবং তার সমাধান নিয়ে যে সব ডাটা স্ট্রাকচার একত্রিত করা হয়েছে সেগুলাকেই একত্রে বলা হয় কালেকশান । কালেকশান মানে হল সমষ্টি । এটি এমন কিছু ডাটা স্ট্রাকচারের সমষ্টি যেগুলার প্রতিটিই বিভিন্ন ডাটাকে সমষ্টিত করে রাখে । হ্যা অ্যারেকেও লো লেভেল এক প্রকার কালেকশান বলা যেতে পারে তবে মডার্ন কালেকশন ফ্রেমওয়ার্কের মাঝে এটিকে ধরা হয়না ।
কালেকশান ইন্টারফেস (Collection Interface)
ইন্টারফেস কি সেটি আপনারা খুব ভালোভাবেই জানেন । যদি না যেনে থাকেন তবে চ্যাপটার ৫.১ পড়ে আসুন । কালেকশান একটি ইন্টারফেস । যেই ইন্টারফেসের মধ্য বলে দেওয়া হয়েছে কোন একটি ক্লাসকে কালেকশান ফ্রেমওয়ার্কের অন্তর্গত হতে গেলে কি কি বৈশিষ্ট থাকতেই হবে । কালেশনগুলা সাধারনত java.util
প্যকেজের অন্তর্গত ।
সবার আগে আমাদের জানা প্রয়োজন কেনই বা আমরা কালেকশনস নিয়ে কাজ করবো ? এটি না নিয়েও তো কাজ করা যেতো । তাহলে কালেকশন কেন !
ওয়েল , আপনাদের কিছুটা উত্তর আমি আগেই দিয়ে দিয়েছি ।
১)অ্যারে নিয়ে কাজ করার সময় আপনি ফিক্সড লেন্থের বাইরে কাজ করতে পারতেন না । অ্যারের বাউন্ডারি ফিক্সড এবং এটি বাড়ানো বা কমানোর কোন সুযোগ নেই রানটাইমে । কালেকশন এই সমস্যার সমাধান করেছে । এটির সাইজ আপনার প্রয়োজন মত বাড়াতে এবং কমাতে পারবেন ।
২)লিংক লিস্ট নিয়ে কাজ করার সময় আপনি ইনডেক্সের সুবিধা পাবেন না । এটা একটা বড় সমস্যার কারন, কালেকশনে আপনি ইন্ডেক্স সুবিধা পাবেন ।
৩)কেবল প্রিমিটিভ নয়, সকল প্রকার অবজেক্ট এমনি একটি কালেকশনের মাঝে আরেকটি কালেকশন নিয়ে কাজ করার মত ফ্লেক্সিবিলিটি পাবেন ।
এছাড়া আরো বহুত সুবিধা আছে যেগুলা কাজ করতে করতে বুঝে যাবেন ।
নিচে কালেকশান ফ্যামিলি ট্রি দেখানোর চেষ্টা করা হল ।
লিস্ট ( List )
লিস্ট List
একটি ইন্টারফেস যেটি সরাসরি Collection
ইন্টারফেসকে এক্সটেন্ড করেছে । এটি যেহেতু একটি ইন্টারফেস ( interface
) তাই আমরা সরাসরি এটার কোন অবজেক্ট বা ইন্সট্যান্স ক্রিয়েট করতে পারবো না । এজন্য অবশ্য আমাদের চিন্তার খুব বেশি কারন নেই । List
ইন্টারফেসকে ইমপ্লিমেন্ট করেছে ArrayList
, Vector
এবং LinkedList
ক্লাস । আমরা খুব সহজে এগুলার মাধ্যমে List
এর অবজেক্ট তৈরি করতে পারি । List
হল আনসর্টেড অবজেক্ট কনটেইনার যেটি ডাটা ডুপ্লিকেসি সাপোর্ট করে । মানে একই ডাটা একাধিকবার থাকতে পারে লিস্টের মাঝে ।
List
ডিক্লেয়ার করার নানা ধাপঃ
ধাপ ১ঃ
ধাপ ২ঃ
এমনকি কেউ চাইলে কালেকশনের অবজেক্ট নিয়েও কাজ করতে পারেন সেক্ষেত্রে যেটি করতে হবে ।
ওকে অনেক হয়েছে । এবার কাজের কথায় আসা যাক । List
নিয়ে কিভাবে কাজ করা যায় সেটাইতো জানা হলোনা এখনো ! ওকে আর বেশি বক বক করে আপনাদের ধৈর্য্যের পরীক্ষা নিবনা । প্রথমে আমরা দেখবো কিভাবে একটি লিস্টে ডাটা অ্যাড বা অ্যাসাইন করতে হয় ।
লিস্টে ডাটা ইনসার্ট(Insert into List)
উপরোক্ত কোডে <Integer>
দিয়ে বোঝানো হয়েছে এই লিস্টটি কেবল ইন্টিজার টাইপ ডাটার জন্য কাজ করবে । এটিকে জেনেরিক বলা হয় । চ্যাপটার ৮ এ আপনাদের এ বিষয়ে জানা কথা । তারপর ArrayList
এর কনস্ট্রাকটর দিয়ে list
অবজেক্টকে ইন্সট্যানশিয়েট করা হয়েছে । add
মেথড এই লিস্টে একটি একটি করে ডাটা অ্যাড করে এবং একটি বুলিয়ান ভ্যালু রিটার্ন করে । যদি কোন কারনে কোন ডাটা অ্যাড করতে ব্যার্থ হয় তবে false
ভ্যালু রিটার্ন করে ।
add(int index, E element)
মেথডটি যেকোন একটি এলিমেন্ট লিস্টের নির্দিষ্ট ইনডেক্সে ইনসার্ট করে । addAll(Collection<? Extends E> c)
মেথডটি ইনপুট প্যারামিটার হিসাবে অন্য কোন একটি লিস্ট বা কালেকশন নিয়ে তার প্রতিটি এলিমেন্ট একটু একটি করে এই লিস্টে ইনসার্ট করে দেয় । addAll(int index, Collection<? Extends E> c)
মেথডটি ঠিক আগের মতই কাজ করে । নির্দিষ্ট ইনডেক্স থেকে অন্য একটি কালেকশনকে ইনজেক্ট করতে থাকে নতুন লিস্টের মাঝে ।
লিস্ট থেকে ডাটা রিড করা(Read from List)
উপরের কোড সেগমেন্টটি মনে করলাম আছে । আমরা কেবল ডাটা রিড করার জন্য কোডটি লিখবো । আমরা বেশ কয়েকভাবে দেখবো যে কিভাবে একটি লিস্ট থেকে ডাটা রিড করা যায় এবং এর মাধ্যমে আরো কিছু মেথড সম্পর্কে জেনে নিব ।
পদ্ধতি ১ঃ
এটি একেবারে চীরাচরিত পদ্ধতি হলেও বেশ কার্যকর । এখানে অ্যারের মত ইন্ডেক্স নিয়ে খেলা করার সুযোগ আছে । size
মেথডটি একটি ইন্টিজার নাম্বার রিটার্ন করে যেটি নির্দেশ করে এই লিস্টে মোট কতগুলা এলিমেন্ট আছে । মানে এই লিস্টের সাইজ কত । get
মেথডটি একটি ইন্টিজার নাম্বার ইনপুট হিসাবে নেয় এবং সেই ইন্ডেক্সের এলিমেন্টটি রিটার্ন করে । এমন কোন ইনডেক্স যদি ইনপুট হিসাবে দেওয়া হয় যেটি এই লিস্টের সাইজের মাঝে পড়েনা তাহলে java.lang.IndexOutOfBoundsException
এক্সেপশন থ্রো করবে ।
পদ্ধতি ২ঃ
এটি একেবারে চীরাচরিত পদ্ধতি থেকে একটু আধুনিক । এনহ্যান্স ফর লুপ । এই পদ্ধতিতে এনহ্যান্স ফর লুপ লিস্ট থেকে একটি একটি এলিমেন্ট প্রতি এলিমেন্টে পিক করে x
ভ্যারিয়েবলের মাঝে রেফার করছে এবং সেটিই আমাদের সামনে প্রদর্শিত হচ্ছে ।
পদ্ধতি ৩ঃ
এটি আরো একটু মডারেট পদ্ধতি । এই পদ্ধতিতে প্রথমেই Iterator
ইন্টারফেসের একটি ইন্সট্যান্স ক্রিয়েট করা হচ্ছে লিস্টের iterator
মেথডটি কল করে । এই মেথডটি একটি ইটারেটর অবজেক্ট রিটার্ন করে যেটি এই লিস্টে টপ টু বটম ইটারেট করতে পারে । ইটারেটরের hasNext
মেথডটি একটি বুলিয়ান ভ্যালু রিটার্ন করে । প্রতি ইটারেশনের পর সে বলে দেয় এর পর আর কোন এলিমেন্ট অবশিষ্ট আছে কি না । ইটারেটরের next
মেথডটি প্রতিবার নতুন একটি এলিমেন্ট প্রভাইড করে এবং এটির কাউন্টার পয়েন্টার তার পরের ইনডেক্সে শিফ্ট করে । যাতে করে পরেরবার নতুন একটি এলিমেন্ট রিটার্ন করতে পারে ।
পদ্ধতি ৪ঃ
হাল আমলের আলোচিত পদ্ধতি । এটিকে বলা হয় ফাংশনাল অপারেশন । জেডিকে ৮ এ এটিকে পরিচিত করানো হয়েছে । অনেকটা ফাংশনাল প্রাগ্রামিং এর মত করেই ডিজাইন করা করা । forEach
মেথডটি একটি একটি করে এলিমেন্ট ট্রাভার্স করে যায় এবং তাকে যে কাজ করতে বলা হয় ঠিক সেই কাজটিই করে বসে থাকে । :D দারুন মজার এই ফাংশনার অপারেশন ।
লিস্টের ভ্যালু রিপ্লেস করা
কোন একটি লিস্ট থেকে খুব সহজেই একটি ভ্যালু রিপ্লেস করে দেওয়া যায় । set(int index, E element)
মেথডটি ২ টি ইনপুর প্যারামিটার নেয় । প্রথমে যে ইনডেক্সের ভ্যালু রিপ্লেস করতে হবে সেটি এবং তার পরে যে অবজেক্ট দিয়ে সেই স্থান পূরন করতে হবে সেটি।
লিস্ট থেকে ডিলিট করা
খুব প্রচলিত ২ উপায়ে লিস্ট থেকে কোন একটি এলিমেন্ট ডিলিট বা রিমুভ করে দেওয়া যায় । একটি হল কোন একদি এলিমেন্ট বা অবজেক্ট কোন ইনডেক্সে আছে সেটা জানা এবং সেই ইনডেক্সকে রিমুভ করে দেওয়া । অথবা যে অবযেক্টটি রিমুভ করতে চাওয়া হচ্ছে সেই অবযেক্টটি দিয়ে বলা সেটি ডিলিট করতে । চলুন দেখি সেটি কিভাবে করা যায়ঃ
পদ্ধতি ১ঃ
এই পদ্ধতি আপনি প্রিমিটিভ ইন্টিজার নাম্বার নাম্বার ইনপুট প্যারামিটার হিসাবে পাস করছেন । অর্থাৎ remove
মেথডটি এটিকে ইনডেক্স হিসাবে বিবেচনা করবে । যদি 2 নাম্বার ইনডেক্সে অন্য কোন নাম্বার থাকে এবং ২ লিস্টে উপস্থিত থাকে তার পরেও সে ২ নাম্বার ইনডেক্সের ভ্যালুটিকে রিমুভ করবে এবং ওই ইনডেক্সের ভ্যালুটি রিটার্ন করবে ।
পদ্ধতি ২ঃ
এই পদ্ধতিতে আপনার লিস্টটি যে টাইপের অবজেক্ট কনটেইন করছে সেই টাইপের একটি অবজেক্ট দিলে সেটিকে ডিলিট করার চেষ্টা করবে । যদি উক্ত অবজেক্ট উপস্থিত থাকে ডিলিট করবে এবং true
ভ্যালু রিটার্ন করবে অন্যথায় false
রিটার্ন করবে ।
লিস্ট সম্পর্কিত কিছু মেথড(Some methods of List)
clear
মেথডটি উক্ত লিস্ট থেকে সব এলিমেন্ট রিমুভ করে দেয় । contains
মেথডটি একটি অবজেক্ট ইনপুট হিসাবে নেয় এবং চেক করে যে উক্ত অবজেক্টরি লিস্টে প্রেজেন্ট কি না । indexOf
মেথসটি একটি অবজেক্ট ইনপুট হিসাবে নেয় এবং যদি সেই অবজেক্টটি ওই লিস্টে প্রেজেন্ট থাকে তবে তার ইনডেক্স রিটার্ন করে । অন্যথায় -১ রিটার্ন করে । sort
নামক একটি মেথড আছে যেটি ইনপুট প্যারামিটার হিসাবে কম্পারেটর অবজেক্ট নিয়ে লিস্টটি সেই অনুযায়ী সর্ট করে ।
এরকম আরো বেশ কিছু মেথড এবং তাদের বিস্তর ব্যাখ্যা ওরাকলের অফিসিয়াল ডকুমেন্টেশন সাইটে পাওয়া যাবে । আগ্রহীরা সেখান থেকে দেখে নিতে পারেন । লিংকঃ http://docs.oracle.com/javase/8/docs/api/java/util/List.html
লিস্ট সর্ট করা(Sort a List)
কোন একটি লিস্টকে সর্ট করার চেয়ে সহজ বিষয় আর কিছু হতেই পারেনা । তবে সমস্যা হল একটি লিস্টকে সর্ট করার নানাবিধ উপায় থাকায় আপনি কনফিউজ হয়ে যেতে পারেন যে আসলে কক্ষন কোন পদ্ধতিতে সর্ট করবেন । আমি নিজেও মাঝে মাঝে কনফিউজ হয়ে যাই । যাইহোক আমরা লিস্ট সর্টিং এর একেবারে বেসিক থেকে ধীরে ধীরে সামনের দিকে এগিয়ে যাব । বলে রাখা ভালো আমরা এখানে বেসিক্যালি ২ প্রকারের সর্টিং টেকনিক দেখবো এবং তাদের আবার ২ প্রকার সাব সর্টিং টেকনিক দেখবো । আগ্রহীরা আরো কিছুটা ঘাটাঘাটি করলে আরো অনেক কিছুই জানতে পারবে ।
পদ্ধতি ১ঃ
এখানে আমরা Collections
ক্লাসের একটি মেথড sort
যেটি ইনপুট প্যারামিটার হিসাবে একটি লিস্ট অবজেক্ট নেয় এবং সেটিকে ইনপ্লেস সর্ট করে দেয় । অর্থাৎ এই মেথডের রিটার্ন টাইপ ভয়েড । এবং এটি অ্যাসেন্ডিং ( ছোট থেকে ক্রমান্বয়ে বড় ) অর্ডারে সর্ট করে ।
আমরা যদি ডিসেন্ডিং অর্ডারে সর্ট করতে চাই তবে আমাদের আরেকটু কাজ বেশি করতে হবে । আর সেটি হল sort
নামক মেথডে আরেকটি প্যারামিটার পাস করতে হবে যেটি আসলে একটি Comparator
অবজেক্ট । যেটার মাধ্যমে আমরা বলে দিব যে আসলে সর্টটি কোন অর্ডারে হবে বা কোন এলিমেন্টের সাপেক্ষে হবে । কোডটিকে সেক্ষেত্রে আমরা এভাবে লিখতে পারতাম,
উল্লেখ্য এখানে Comparator
একটি ইন্টারফেস এবং এবং compare
একটি abstract
মেথড তাই আমাদের এটিকে ইমপ্লিমেন্ট করতে হয়েছে । compare
মেথডটি একটি ইন্টিজার নাম্বার রিটার্ন করে । দুটি অ্যাট্রিবিউটের মাঝে কম্পেয়ার করে পজেটিভ, নেগেটিভ বা শুন্য রিটার্ন করে । শুন্য রিটার্ন করা মানে দুটি সমান । পজেটিভ রিটার্ন করা মানে প্রথমটি বড় আর অন্যথায় ছোট । আমরা আলাদা ভাবে Comparator
এর অবজেক্ট ক্রিয়েট না করেও কাজটি করতে পারতাম ইনপ্লেসে । সেক্ষেত্রে এরকম হতে পারত,
বর্তমান সময় যেহেতু ল্যামডা এক্সপ্রেশনের যুগ চলছে তাই এটিকে আরো সহজে এবং খুব সংক্ষেপে এভাবেও লেখা যেত,
কাজ বেসিক্যালি সব একই ভাবে করছে ।
এতক্ষন আমরা দেখলাম প্রিমিটিভ টাইপের ডাটার একটি লিস্ট সর্ট করা । এমনতো হতেই পারে যে আপনার কাছে একটি কাষ্ট টাইপের অবজেক্ট কনটেইন করে এমন একটি লিস্ট সর্ট করতে হবে ওই অবজেক্টের নির্দিষ্ট কোন এক বা একাধিক প্রপার্টির সাপেক্ষে । সেক্ষেত্রে করনীয় কি সেটা এবার চলুন দেখে ফেলি ।
ঠিক আগের মতই কাজ করতে পারবেন । তবে এখানে অবজেক্ট নিয়ে কাজ করতে হবে । এবং অবজেক্টের কোন ফিল্ডের রেসপেক্টে সর্ট করতে চাচ্ছেন সেটাও ডিফাইন করে দিতে হবে । অ্যাসেন্ডিং বা ডিসেন্ডিং যেকোন ভাবেই সর্ট করতে পারবে । এমনকি একাধিক ফিল্ডের রেসপেক্টে যদি সর্ট করতে চান সেটাও করতে পারবে । আপনারা চাইলে ল্যামডা এক্সপ্রেশন ব্যাবহার করতে পারতেন সেক্ষেত্রে এরকম হতো কোডটি,
এবার আমরা একটু ভিন্ন একটা পদ্ধতি দেখবো । যদি এমন হয় যে আমাদের এই ক্লাসটি প্রায়ই সর্ট করতে হয় এবং নির্দিষ্ট একটা অর্ডারে সর্ট করতে হয় , সেক্ষেত্রে আমরা একটা বিশেষ কাজ করতে পারি । আমরা Comparable
ইন্টারফেসটি ইমপ্লিমেন্ট করতে পারি । Comparable
ইন্টারফেসের মাঝে compareTo
মেথডটি অভাররাইড করলেই কাজ শেষ । অ্যাসেন্ডিং বা ডিসেন্ডিং আগের মতই । তবে চলুন দেখি কিভাবে সেটি করা যায় সেটি দেখে ফেলি ।
এভাবে খুব সহজেই আমরা একটি অবজেক্টের লিস্ট সর্ট করতে পারি । তবে একটি বিষয় লক্ষ করার মত বিষয় হচ্ছে যে আপনাদের যে ২ প্রকারের সর্ট দেখানো হয়েছে অবজেক্টের লিস্টের ক্ষেত্রে এই দুই প্রকার কিন্তু একত্রেও ব্যাবহার করতে পারবেন । তবে সেক্ষেত্রে প্রায়োরিটি পাবে ক্লোজার ফাংশন । চলুন দেখি বিষয়টা কি একটু দেখে নেই ।
এখানে যদিও Employee
ক্লাস Comparable
ইন্টারফেস ইমপ্লিমেন্ট করেছে এবং compareTo
মেথডে বলে দেওয়া হয়েছে age
এর অ্যাসেন্ডিং অর্ডারে সর্ট করতে হবে কিন্তু এটি সর্ট করবে salary
এর ডিসেন্ডিং অর্ডারে । কেন সেটা করছে সেটা নিশ্চয় বুঝতে পেরেছেন ।
আপনারা চাইলে কিন্তু List
এর অন্তর্গত sort
মেথড ব্যাবহার করেও সর্ট করতে পারতেন । সেটা করার জন্য খুব বেশি কিছুই করতে হতনা । সেটি অলরেডি আপনারা জানেন কিভাবে সেটি করা যায় ।
বেসিক্যালি এভাবে খুব সহজেই একটি লিস্ট সর্ট করা যায় । আপনারা আরো বেশি আগ্রহী হলে ওরাকলের ডকুমেন্টেশন পড়তে পারেন । আরো বেশি পরিষ্কার হবে ধারনা ।
–-------চলবে--------
Last updated