স্কালায় কালেকশন ফ্রেমওয়ার্ক খুবই শক্তিশালী এবং নমনীয়, যা ডাটা সংগ্রহ ও পরিচালনার জন্য বিভিন্ন ডাটা স্ট্রাকচার এবং ফাংশনাল অপারেশন প্রদান করে। স্কালার কালেকশনগুলি প্রোগ্রামিংয়ে অধিক কার্যকারিতা এবং পরিচ্ছন্নতা আনে, এবং এতে রয়েছে ইমিউটেবল (immutable) ও মিউটেবল (mutable) কালেকশন, যা সাইড-এফেক্ট মুক্ত এবং দ্রুত পারফরম্যান্স নিশ্চিত করে।
স্কালার কালেকশন ফ্রেমওয়ার্কের দুটি প্রধান অংশ:
- Immutable Collections (যেগুলি একবার তৈরি হলে পরিবর্তন করা যায় না)
- Mutable Collections (যেগুলি তৈরি হওয়ার পর পরিবর্তিত হতে পারে)
স্কালা কালেকশন বিভিন্ন ডাটা স্ট্রাকচার যেমন List, Set, Map, Queue, ইত্যাদি সমর্থন করে। এখানে আমরা এই কালেকশনগুলির ব্যাবহার ও কিছু গুরুত্বপূর্ণ ফিচার নিয়ে আলোচনা করব।
১. Immutable Collections
স্কালায় immutable collections ব্যবহার করা হয় যখন আপনি চান যে ডেটা পরিবর্তন না হোক বা একটি নতুন কালেকশন তৈরি করা হোক, কিন্তু মূল কালেকশনটি অপরিবর্তিত থাকুক। Immutable কালেকশনগুলি স্কালার ডিফল্ট এবং ফাংশনাল প্রোগ্রামিং শৈলী অনুসারে নিরাপদ।
১.১ List
List হল একটি ইমিউটেবল সিকোয়েন্স কালেকশন যা এলিমেন্টগুলিকে অর্ডার অনুসারে রাখে।
উদাহরণ:
val numbers = List(1, 2, 3, 4, 5)
val updatedNumbers = numbers.map(_ * 2)
println(numbers) // Output: List(1, 2, 3, 4, 5)
println(updatedNumbers) // Output: List(2, 4, 6, 8, 10)এখানে:
numbersএকটি ইমিউটেবল List, এবং map ফাংশন ব্যবহার করে একটি নতুন লিস্ট তৈরি হয়েছে।
১.২ Set
Set হল একটি কালেকশন যা প্রতিটি উপাদানকে এককভাবে ধারণ করে (যেমন, ডুপ্লিকেট এলিমেন্ট থাকতে পারে না)।
উদাহরণ:
val uniqueNumbers = Set(1, 2, 3, 3, 4)
println(uniqueNumbers) // Output: Set(1, 2, 3, 4)এখানে:
Setডুপ্লিকেট মানগুলো সরিয়ে ফেলে, শুধুমাত্র ইউনিক (একক) মানগুলো রাখে।
১.৩ Map
Map হল একটি কালেকশন যেখানে key-value পেয়ার ব্যবহার করা হয়।
উদাহরণ:
val capitals = Map("USA" -> "Washington D.C.", "India" -> "New Delhi")
println(capitals) // Output: Map(USA -> Washington D.C., India -> New Delhi)এখানে:
Mapএকটি key-value পেয়ার সংরক্ষণ করে, যেখানে প্রতি key এর একটি নির্দিষ্ট value থাকে।
২. Mutable Collections
স্কালায় mutable collections এমন কালেকশন যেখানে আপনি ডেটা পরিবর্তন বা আপডেট করতে পারেন। এসব কালেকশন কার্যকরী যখন আপনি চান কালেকশনের মধ্যে নতুন মান যুক্ত করা বা পুরানো মান পরিবর্তন করতে।
২.১ Mutable ListBuffer
ListBuffer হল একটি মিউটেবল সিকোয়েন্স কালেকশন যা দ্রুত উপাদান সংযোজন বা অপসারণে সহায়তা করে।
উদাহরণ:
import scala.collection.mutable.ListBuffer
val buffer = ListBuffer(1, 2, 3)
buffer += 4 // Add element
buffer -= 2 // Remove element
println(buffer) // Output: ListBuffer(1, 3, 4)এখানে:
+=অপারেটর ব্যবহার করে নতুন মান যোগ করা হয়েছে এবং-=অপারেটর দিয়ে পুরানো মান মুছে ফেলা হয়েছে।
২.২ Mutable Set
Set এর মিউটেবল সংস্করণ যা আপনাকে ডুপ্লিকেট এলিমেন্ট সংরক্ষণ না করে কালেকশন আপডেট করতে দেয়।
উদাহরণ:
import scala.collection.mutable.Set
val mutableSet = Set(1, 2, 3)
mutableSet += 4
mutableSet -= 2
println(mutableSet) // Output: Set(1, 3, 4)এখানে:
+=এবং-=অপারেটর ব্যবহার করেSetএ উপাদান যোগ এবং অপসারণ করা হচ্ছে।
২.৩ Mutable Map
Map এর মিউটেবল সংস্করণ, যেখানে আপনি key-value পেয়ার আপডেট করতে পারেন।
উদাহরণ:
import scala.collection.mutable.Map
val mutableMap = Map("USA" -> "Washington", "India" -> "New Delhi")
mutableMap("UK") = "London" // Add new key-value pair
mutableMap("India") = "Delhi" // Update existing key
println(mutableMap) // Output: Map(USA -> Washington, India -> Delhi, UK -> London)এখানে:
mutableMapএ নতুনkey-valueপেয়ার যোগ করা এবং পুরোনোvalueআপডেট করা হয়েছে।
৩. স্কালার কালেকশন মেথডস (Common Methods)
স্কালা কালেকশন ফ্রেমওয়ার্কে কিছু সাধারণ মেথড রয়েছে যা প্রায় প্রতিটি কালেকশন টাইপে ব্যবহৃত হয়। নিচে কিছু প্রধান মেথড দেওয়া হল:
- map: কালেকশনের প্রতিটি উপাদানের উপর ফাংশন প্রয়োগ করে একটি নতুন কালেকশন তৈরি করে।
- filter: একটি শর্ত অনুযায়ী কালেকশন থেকে উপাদান ফিল্টার করে।
- reduce: কালেকশনের উপাদানগুলোকে একত্রিত করে একটি একক মানে রিডিউস করে।
- flatMap: একটি কালেকশন থেকে অন্য কালেকশন তৈরি করে।
- foreach: প্রতিটি উপাদানকে প্রক্রিয়া করে, কিন্তু একটি নতুন কালেকশন রিটার্ন করে না।
উদাহরণ:
val numbers = List(1, 2, 3, 4, 5)
val doubled = numbers.map(_ * 2)
println(doubled) // Output: List(2, 4, 6, 8, 10)
val evenNumbers = numbers.filter(_ % 2 == 0)
println(evenNumbers) // Output: List(2, 4)
val sum = numbers.reduce(_ + _)
println(sum) // Output: 15এখানে:
- map ব্যবহার করে প্রতিটি উপাদানের উপর ফাংশন প্রয়োগ করা হয়েছে।
- filter ব্যবহার করে শুধুমাত্র even সংখ্যাগুলি ফিল্টার করা হয়েছে।
- reduce ব্যবহার করে সব উপাদান যোগ করা হয়েছে।
৪. কলেকশন ফ্রেমওয়ার্কের উপকারিতা
- সক্ষমতা: স্কালার কালেকশনগুলি তাদের উচ্চ স্তরের কার্যক্ষমতা এবং দক্ষতার জন্য বিখ্যাত।
- নিরাপত্তা: ইমিউটেবল কালেকশন ব্যবহারের মাধ্যমে কোডে সাইড-এফেক্ট কমানো যায়।
- স্বচ্ছতা: উচ্চস্তরের ফাংশনাল অপারেশনগুলি যেমন
map,filter,fold,reduceব্যবহারের মাধ্যমে কোড আরও পরিষ্কার হয়। - অফারিং: স্কালা এমন কিছু শক্তিশালী কালেকশন ফিচার প্রদান করে যা অনেক ভাষায় নেই, যেমন
lazyমেথডের মাধ্যমে কার্যক্রম বিলম্বিত করা বাviewঅপশন ব্যবহার করে একটি নতুন কালেকশন তৈরির আগে ইনপুটগুলিকে বিলম্বিতভাবে যাচাই করা।
সারাংশ
স্কালার কালেকশন ফ্রেমওয়ার্ক অত্যন্ত শক্তিশালী এবং বহুমুখী, যা আপনাকে ডাটা সঞ্চয় ও পরিচালনা করতে অনেক সুবিধা প্রদান করে। Immutable Collections ডেটার নিরাপত্তা নিশ্চিত করে এবং Mutable Collections দ্রুত আপডেট এবং পরিবর্তন পরিচালনা করতে সক্ষম। স্কালার কালেকশন ফ্রেমওয়ার্কের মাধ্যমে কোড লেখার সময় কার্যকারিতা এবং পরিষ্কারতা অর্জন করা সম্ভব, যা উন্নত সফটওয়্যার ডেভেলপমেন্টে সহায়ক।
স্কালায় লিস্ট এবং অ্যারেগেট (Array) দুটি গুরুত্বপূর্ণ ডেটা স্ট্রাকচার। এগুলোর মধ্যে কিছু মৌলিক পার্থক্য রয়েছে এবং বিভিন্ন পরিস্থিতিতে একে অপরের তুলনায় উপযুক্ত হতে পারে। এখানে আমরা স্কালার লিস্ট এবং অ্যারেই এর ব্যবহারের পার্থক্য এবং উদাহরণ দেখব।
১. স্কালার লিস্ট (List)
লিস্ট স্কালায় একটি ইমিউটেবল (immutable) ডাটা স্ট্রাকচার, অর্থাৎ একবার লিস্ট তৈরি হলে তার উপাদান পরিবর্তন করা যায় না। লিস্টে একাধিক উপাদান থাকতে পারে এবং এটি অর্ডারকৃত (ordered)।
স্কালার লিস্টের বৈশিষ্ট্য:
- ইমিউটেবল: একবার তৈরি হলে লিস্টে উপাদান পরিবর্তন করা যায় না।
- অর্ডারকৃত: লিস্টের মধ্যে উপাদান গুলি একটি নির্দিষ্ট অর্ডারে থাকে।
- হেড এবং টেল: লিস্টে প্রথম উপাদানকে হেড এবং বাকি উপাদানগুলিকে টেল বলে অভিহিত করা হয়।
লিস্টের তৈরি এবং ব্যবহার:
object ListExample {
def main(args: Array[String]): Unit = {
// লিস্ট তৈরি
val fruits = List("Apple", "Banana", "Cherry")
// লিস্টের উপাদান এক্সেস করা
println(fruits.head) // Output: Apple
println(fruits.tail) // Output: List(Banana, Cherry)
// নতুন উপাদান যোগ করা (লিস্টে যোগ করা মানে নতুন লিস্ট তৈরি)
val newFruits = "Orange" :: fruits
println(newFruits) // Output: List(Orange, Apple, Banana, Cherry)
}
}এখানে:
Listএকটি ইমিউটেবল ডাটা স্ট্রাকচার এবং::অপারেটর ব্যবহার করে নতুন উপাদান যোগ করা হয়েছে।.headপ্রথম উপাদান এবং.tailবাকি উপাদানগুলো পেতে ব্যবহার করা হয়েছে।
লিস্টে কিছু সাধারণ অপারেশন:
::: একটি নতুন উপাদান যোগ করা।++: দুটি লিস্ট একত্রিত করা।map: লিস্টের প্রতিটি উপাদানের উপর একটি ফাংশন প্রয়োগ করা।
val numbers = List(1, 2, 3, 4)
val doubledNumbers = numbers.map(_ * 2) // Output: List(2, 4, 6, 8)
println(doubledNumbers)২. স্কালার অ্যারে (Array)
অ্যারেই স্কালায় একটি মিউটেবল (mutable) ডাটা স্ট্রাকচার, যার মধ্যে উপাদানগুলি নির্দিষ্ট ইনডেক্স দ্বারা অ্যাক্সেস করা যায় এবং উপাদান পরিবর্তন করা যায়।
স্কালার অ্যারের বৈশিষ্ট্য:
- মিউটেবল: অ্যারে তৈরি হওয়ার পর তার উপাদান পরিবর্তন করা যেতে পারে।
- ফিক্সড সাইজ: অ্যারে একটি নির্দিষ্ট সাইজের ডাটা স্ট্রাকচার, একবার অ্যারে তৈরি হয়ে গেলে তার সাইজ পরিবর্তন করা যায় না।
- র্যান্ডম অ্যাক্সেস: অ্যারে থেকে উপাদান নির্দিষ্ট ইনডেক্স ব্যবহার করে খুব দ্রুত অ্যাক্সেস করা যায়।
অ্যারে তৈরি এবং ব্যবহার:
object ArrayExample {
def main(args: Array[String]): Unit = {
// অ্যারে তৈরি
val numbers = Array(1, 2, 3, 4, 5)
// অ্যারের উপাদান এক্সেস করা
println(numbers(0)) // Output: 1
println(numbers(4)) // Output: 5
// অ্যারে উপাদান পরিবর্তন করা
numbers(0) = 10
println(numbers(0)) // Output: 10
}
}এখানে:
- অ্যারের উপাদান পরিবর্তন করা হয়েছে
numbers(0) = 10স্টেটমেন্টের মাধ্যমে। - অ্যারে ইন্ডেক্স শুরু হয়
0থেকে।
অ্যারে কিছু সাধারণ অপারেশন:
update: অ্যারে উপাদান পরিবর্তন করা।map: অ্যারের প্রতিটি উপাদানের উপর ফাংশন প্রয়োগ করা।foreach: অ্যারের প্রতিটি উপাদান এর উপর একটি কার্যক্রম প্রয়োগ করা।
val arr = Array(1, 2, 3, 4)
arr.foreach(println) // Output: 1 2 3 4৩. লিস্ট এবং অ্যারের পার্থক্য
| বৈশিষ্ট্য | লিস্ট (List) | অ্যারে (Array) |
|---|---|---|
| ইমিউটেবল বা মিউটেবল | ইমিউটেবল (Immutable) | মিউটেবল (Mutable) |
| সাইজ | ভ্যারিয়েবল সাইজ (এটা পরিবর্তন করা যায় না) | ফিক্সড সাইজ (এটা একবার তৈরি হলে পরিবর্তন করা যায় না) |
| ডাটা অ্যাক্সেস | হেড এবং টেল দিয়ে অ্যাক্সেস করা হয় | ইনডেক্স ব্যবহার করে দ্রুত অ্যাক্সেস করা যায় |
| কনটেইনার টাইপ | এক্সটেনশন সহ নতুন উপাদান যুক্ত করা যায় | অ্যারের সাইজ ফিক্সড |
| পারফরম্যান্স | কিছুটা ধীর গতির (চলতি উপাদান পরিবর্তন না করা হলে) | দ্রুত (র্যান্ডম অ্যাক্সেসের জন্য) |
৪. লিস্ট এবং অ্যারে কবে ব্যবহার করবেন?
- লিস্ট: আপনি যদি একটি ইমিউটেবল ডাটা স্ট্রাকচার চান এবং উপাদানগুলোর সাথে অনেক ফাংশনাল অপারেশন (যেমন:
map,filter,reduceইত্যাদি) করতে চান, তাহলে লিস্ট ব্যবহার করুন। - অ্যারেই: যদি আপনি একটি মিউটেবল ডাটা স্ট্রাকচার চান এবং দ্রুত র্যান্ডম অ্যাক্সেস (ইনডেক্সিং) এবং উপাদান পরিবর্তন করতে চান, তবে অ্যারে ব্যবহার করুন।
সারাংশ
- লিস্ট: স্কালায় লিস্ট একটি ইমিউটেবল ডাটা স্ট্রাকচার যা সহজে রূপান্তরযোগ্য এবং অপারেশনগুলির জন্য উপযুক্ত।
- অ্যারেই: অ্যারে একটি মিউটেবল ডাটা স্ট্রাকচার, যা দ্রুত র্যান্ডম অ্যাক্সেস এবং উপাদান পরিবর্তনের জন্য আদর্শ।
এখন আপনি বুঝতে পারছেন যে স্কালার লিস্ট এবং অ্যারে কোন পরিস্থিতিতে ব্যবহার করা উচিত।
স্কালা একটি শক্তিশালী এবং বহুমুখী প্রোগ্রামিং ভাষা, যা মিউটেবল (Mutable) এবং ইমিউটেবল (Immutable) কালেকশন প্রদান করে। এগুলি ডাটা স্ট্রাকচারের বিভিন্ন ধরনের কাজ সম্পাদন করতে ব্যবহৃত হয়। স্কালায় কালেকশনগুলি মূলত এমন ডেটা স্ট্রাকচার যা একাধিক উপাদান সংরক্ষণ করে এবং সেই উপাদানগুলোর সাথে বিভিন্ন ধরনের অপারেশন (যেমন যোগ, মুছে ফেলা, পরিবর্তন করা) করার সুযোগ দেয়।
এখানে মিউটেবল এবং ইমিউটেবল কালেকশনগুলির মধ্যে পার্থক্য এবং ব্যবহারবিধি নিয়ে আলোচনা করা হলো।
১. ইমিউটেবল কালেকশন (Immutable Collections)
ইমিউটেবল কালেকশনগুলি এমন ডেটা স্ট্রাকচার, যেখানে একবার কোনো মান অ্যাসাইন করার পর তা আর পরিবর্তন করা যায় না। যখন আপনি একটি নতুন মান যোগ বা মুছে ফেলেন, তখন আসল কালেকশনটি পরিবর্তিত না হয়ে একটি নতুন কালেকশন তৈরি হয়। স্কালায় ইমিউটেবল কালেকশন ডিফল্ট।
১.১ ইমিউটেবল লিস্ট (Immutable List)
List হলো স্কালার একটি অত্যন্ত জনপ্রিয় ইমিউটেবল ডেটা স্ট্রাকচার। একবার তৈরি হলে এর উপাদানগুলি পরিবর্তন করা যায় না।
উদাহরণ:
val numbers = List(1, 2, 3, 4, 5)
// Adding an element to a list creates a new list
val newNumbers = 0 :: numbers // :: is used to prepend an element to the list
println(numbers) // Output: List(1, 2, 3, 4, 5)
println(newNumbers) // Output: List(0, 1, 2, 3, 4, 5)এখানে numbers লিস্টটি অপরিবর্তিত রয়েছে, এবং নতুন লিস্ট newNumbers তৈরি হয়েছে যেখানে 0 উপাদানটি যোগ করা হয়েছে।
১.২ ইমিউটেবল সেট (Immutable Set)
Set হলো একটি কালেকশন যেখানে উপাদানগুলো অর্ডারহীন এবং একই মান একাধিক বার থাকতে পারে না। এটি ইমিউটেবল হলে একবার সেটে উপাদান অ্যাসাইন করা হলে সেটে কোনো পরিবর্তন করা যায় না।
উদাহরণ:
val fruits = Set("Apple", "Banana", "Orange")
// Adding an element to the set creates a new set
val newFruits = fruits + "Grapes"
println(fruits) // Output: Set(Apple, Banana, Orange)
println(newFruits) // Output: Set(Apple, Banana, Orange, Grapes)এখানে fruits সেটটি অপরিবর্তিত রয়েছে, এবং newFruits সেটে একটি নতুন উপাদান (Grapes) যোগ করা হয়েছে।
১.৩ ইমিউটেবল ম্যাপ (Immutable Map)
Map হল একটি কী-ভ্যালু পেয়ার কালেকশন। স্কালার ইমিউটেবল Map এ একবার ডাটা অ্যাসাইন করার পর সেটি পরিবর্তন করা যায় না।
উদাহরণ:
val capitals = Map("India" -> "New Delhi", "USA" -> "Washington D.C.")
// Adding a new key-value pair creates a new map
val newCapitals = capitals + ("Japan" -> "Tokyo")
println(capitals) // Output: Map(India -> New Delhi, USA -> Washington D.C.)
println(newCapitals) // Output: Map(India -> New Delhi, USA -> Washington D.C., Japan -> Tokyo)এখানে, capitals মাপটি অপরিবর্তিত রয়েছে, এবং newCapitals ম্যাপে একটি নতুন কী-ভ্যালু পেয়ার যোগ করা হয়েছে।
২. মিউটেবল কালেকশন (Mutable Collections)
মিউটেবল কালেকশনগুলি এমন ডেটা স্ট্রাকচার, যেখানে একবার একটি মান অ্যাসাইন করার পর সেই মান পরিবর্তন বা মুছে ফেলা সম্ভব। মিউটেবল কালেকশনগুলি সাধারণত বেশি কর্মক্ষম হতে পারে, তবে এর মান পরিবর্তনযোগ্য হওয়ায় সতর্কভাবে ব্যবহার করা প্রয়োজন।
২.১ মিউটেবল লিস্ট (Mutable List)
স্কালায় ListBuffer হল একটি মিউটেবল লিস্ট যা ডাটা ম্যানিপুলেশনে সহজ।
উদাহরণ:
import scala.collection.mutable.ListBuffer
val numbers = ListBuffer(1, 2, 3, 4, 5)
numbers += 6 // Adding an element
numbers -= 2 // Removing an element
println(numbers) // Output: ListBuffer(1, 3, 4, 5, 6)এখানে, numbers লিস্টটি মিউটেবল হওয়ায় উপাদান যোগ এবং মুছে ফেলা সম্ভব।
২.২ মিউটেবল সেট (Mutable Set)
Set ধরনের কালেকশনে স্কালায় HashSet বা LinkedHashSet ব্যবহার করা হয় যা মিউটেবল। এর মধ্যে উপাদান যোগ, মুছে ফেলা এবং অন্যান্য পরিবর্তন সম্ভব।
উদাহরণ:
import scala.collection.mutable.Set
val fruits = Set("Apple", "Banana", "Orange")
fruits += "Grapes" // Adding an element
fruits -= "Banana" // Removing an element
println(fruits) // Output: Set(Apple, Orange, Grapes)এখানে fruits সেটে উপাদান যোগ এবং মুছে ফেলা হয়েছে, যেহেতু এটি মিউটেবল।
২.৩ মিউটেবল ম্যাপ (Mutable Map)
Map ধরনের কালেকশনে মিউটেবল মানের জন্য HashMap বা LinkedHashMap ব্যবহার করা হয়।
উদাহরণ:
import scala.collection.mutable.Map
val capitals = Map("India" -> "New Delhi", "USA" -> "Washington D.C.")
capitals += ("Japan" -> "Tokyo") // Adding a new key-value pair
capitals -= "USA" // Removing a key-value pair
println(capitals) // Output: Map(India -> New Delhi, Japan -> Tokyo)এখানে, capitals ম্যাপটি মিউটেবল হওয়ায় এর মধ্যে নতুন উপাদান যোগ করা এবং পুরানো উপাদান মুছে ফেলা সম্ভব।
৩. ইমিউটেবল এবং মিউটেবল কালেকশনের পার্থক্য
| বৈশিষ্ট্য | ইমিউটেবল কালেকশন | মিউটেবল কালেকশন |
|---|---|---|
| পরিবর্তনযোগ্যতা | একবার তৈরি হলে পরিবর্তন করা যায় না | উপাদান যোগ, মুছে ফেলা বা পরিবর্তন করা যায় |
| পারফরম্যান্স | কিছু ক্ষেত্রে কম পারফর্মেন্স হতে পারে | বেশি কর্মক্ষম হতে পারে, কিন্তু সাবধানে ব্যবহার করতে হয় |
| সুরক্ষা | উচ্চ সুরক্ষা, কারণ একবার তৈরি হলে এটি অপরিবর্তনীয় | কম সুরক্ষা, কারণ এর উপাদান পরিবর্তনযোগ্য |
| ব্যবহার | ফাংশনাল প্রোগ্রামিংয়ের জন্য উপযুক্ত | অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিংয়ের জন্য উপযুক্ত |
সারাংশ
- ইমিউটেবল কালেকশন হল এমন ডেটা স্ট্রাকচার, যেখানে একবার একটি মান অ্যাসাইন করা হলে তা পরিবর্তন করা যায় না। এটি সুরক্ষিত এবং সতর্কতার সঙ্গে ব্যবহার করা যায়, বিশেষত ফাংশনাল প্রোগ্রামিংয়ে।
- মিউটেবল কালেকশন হল এমন ডেটা স্ট্রাকচার, যা উপাদান পরিবর্তন বা মুছে ফেলার অনুমতি দেয়, তবে এগুলি সাবধানে ব্যবহার করতে হয়, বিশেষত যখন থ্রেডিং বা পারালাল প্রসেসিংয়ের কথা আসে।
ইমিউটেবল এবং মিউটেবল কালেকশন ব্যবহার করার সময় সঠিক টাইপ নির্বাচন করা খুবই গুরুত্বপূর্ণ, কারণ এটি আপনার কোডের কর্মক্ষমতা এবং সুরক্ষা প্রভাবিত করতে পারে।
স্কালা প্রোগ্রামিং ভাষায় Map এবং Set দুটি গুরুত্বপূর্ণ ডাটা স্ট্রাকচার, যেগুলি বিভিন্ন ধরনের ডাটা সঞ্চয়ের জন্য ব্যবহৃত হয়। এই ডাটা স্ট্রাকচারগুলি স্কালার 컬েকশন লাইব্রেরির অংশ এবং ফাংশনাল প্রোগ্রামিংয়ের সুবিধা নিয়ে কাজ করে।
১. স্কালা ম্যাপ (Map)
Map একটি কনটেইনার ডাটা স্ট্রাকচার যেখানে কী (key) এবং মান (value) পেয়ার হিসেবে ডাটা সংরক্ষণ করা হয়। প্রতিটি কী একক হওয়া প্রয়োজন এবং এর মাধ্যমে আমরা মানকে দ্রুত অ্যাক্সেস করতে পারি।
১.১ Map এর ধরন:
- Immutable Map: স্কালায় ডিফল্টভাবে Immutable Map ব্যবহৃত হয়। মানে, একবার মান অ্যাসাইন করা হলে, তা পরিবর্তন করা যায় না।
- Mutable Map: আপনি চাইলে mutable.Map ব্যবহার করতে পারেন, যেখানে মান পরিবর্তন করা যায়।
১.২ Immutable Map উদাহরণ
object MapExample {
def main(args: Array[String]): Unit = {
// Immutable Map
val capitals = Map("India" -> "New Delhi", "USA" -> "Washington D.C.", "Japan" -> "Tokyo")
// Accessing a value by key
println("Capital of India: " + capitals("India")) // Output: New Delhi
println("Capital of Japan: " + capitals("Japan")) // Output: Tokyo
}
}এখানে:
Mapএকটি কনটেইনার যাIndia,USA, এবংJapanএর রাজধানী সংরক্ষণ করে।"India" -> "New Delhi"হল একটি কী-মান পেয়ার।
১.৩ Mutable Map উদাহরণ
import scala.collection.mutable
object MutableMapExample {
def main(args: Array[String]): Unit = {
// Mutable Map
val mutableCapitals = mutable.Map("India" -> "New Delhi", "USA" -> "Washington D.C.")
// Modifying the value of a key
mutableCapitals("USA") = "Los Angeles" // Changing capital of USA
println("Updated Capital of USA: " + mutableCapitals("USA")) // Output: Los Angeles
}
}এখানে:
mutable.Mapএকটি মিউটেবল ম্যাপ যেখানে মান পরিবর্তন করা সম্ভব।
১.৪ Map এর বিভিন্ন ফাংশন
- map: একটি ফাংশনকে প্রতিটি উপাদানের উপর প্রয়োগ করে নতুন একটি কন্টেইনার রিটার্ন করে।
- get: একটি কী দিয়ে মান বের করা।
- contains: একটি কী-ভিত্তিক পরীক্ষা করা।
val numbers = Map(1 -> "One", 2 -> "Two", 3 -> "Three")
val doubledNumbers = numbers.map { case (key, value) => (key * 2, value) }
println(doubledNumbers) // Output: Map(2 -> One, 4 -> Two, 6 -> Three)
println(numbers.get(2)) // Output: Some(Two)
println(numbers.contains(4)) // Output: false২. স্কালা সেট (Set)
Set একটি কনটেইনার ডাটা স্ট্রাকচার যেখানে অনন্য (unique) উপাদান (elements) সংরক্ষিত থাকে। এটি ডুপ্লিকেট মান সমর্থন করে না, অর্থাৎ একই মান একাধিকবার থাকতে পারে না। স্কালায় সেটের দুটি ধরনের রয়েছে:
- Immutable Set: ডিফল্ট সেট টাইপ যা ইমিউটেবল।
- Mutable Set: যেখানে আপনি ডাটা পরিবর্তন করতে পারবেন।
২.১ Immutable Set উদাহরণ
object SetExample {
def main(args: Array[String]): Unit = {
// Immutable Set
val numbers = Set(1, 2, 3, 4, 5)
// Adding an element (Note: Immutable Set can't be modified directly)
val newNumbers = numbers + 6
println("Original Set: " + numbers) // Output: Set(1, 2, 3, 4, 5)
println("Updated Set: " + newNumbers) // Output: Set(1, 2, 3, 4, 5, 6)
}
}এখানে:
- Immutable Set-এ উপাদান যুক্ত করার সময় সেট পরিবর্তিত হয় না, বরং একটি নতুন সেট তৈরি হয়।
২.২ Mutable Set উদাহরণ
import scala.collection.mutable
object MutableSetExample {
def main(args: Array[String]): Unit = {
// Mutable Set
val mutableNumbers = mutable.Set(1, 2, 3, 4, 5)
// Adding an element (Mutable Set can be modified)
mutableNumbers += 6
println("Updated Set: " + mutableNumbers) // Output: Set(1, 2, 3, 4, 5, 6)
}
}এখানে:
- Mutable Set-এ নতুন উপাদান যুক্ত করা হয়েছে এবং সেটের মান পরিবর্তিত হয়েছে।
২.৩ Set এর বিভিন্ন ফাংশন
- union: দুটি সেটের সমন্বয়।
- intersection: দুটি সেটের মিল।
- difference: দুটি সেটের পার্থক্য।
val setA = Set(1, 2, 3, 4)
val setB = Set(3, 4, 5, 6)
println(setA union setB) // Output: Set(1, 2, 3, 4, 5, 6)
println(setA intersect setB) // Output: Set(3, 4)
println(setA diff setB) // Output: Set(1, 2)এখানে:
- union: দুটি সেটের সমস্ত উপাদান একত্রিত করে।
- intersect: দুটি সেটের মিলিত উপাদানগুলো বের করে।
- diff: এক সেটে থাকা কিন্তু অন্য সেটে না থাকা উপাদানগুলো বের করে।
সারাংশ
- Map একটি কনটেইনার যা কী-মান পেয়ার সংরক্ষণ করে, এবং এটি Immutable এবং Mutable উভয় ধরনে পাওয়া যায়।
- Set একটি কনটেইনার যা শুধুমাত্র unique উপাদান সংরক্ষণ করে এবং এটি Immutable এবং Mutable উভয় ধরনে পাওয়া যায়।
স্কালায় Map এবং Set ব্যবহার করলে ডাটা স্ট্রাকচারের সাথে কাজ করা সহজ হয় এবং ফাংশনাল প্রোগ্রামিংয়ের সুবিধা পাওয়া যায়।
স্কালার ভেক্টর (Vector) এবং স্ট্রিম (Stream) দুটি শক্তিশালী ডাটা স্ট্রাকচার, যা ইমিউটেবল (Immutable) এবং ফাংশনাল প্রোগ্রামিংয়ের সুবিধা প্রদান করে। এগুলোর মধ্যে পার্থক্য এবং ব্যবহার সম্পর্কে বিস্তারিত আলোচনা করা হবে।
১. ভেক্টর (Vector)
ভেক্টর হলো একটি ইমিউটেবল (immutable) অ্যারে-ভিত্তিক ডাটা স্ট্রাকচার, যা দ্রুত ইনডেক্সিং এবং আপডেটের জন্য উপযুক্ত। এটি স্কালার লিস্ট ডাটা স্ট্রাকচারের মতোই ইমিউটেবল, কিন্তু এটি O(log n) সময়জট (time complexity) সহ দ্রুত অ্যাক্সেস প্রদান করে।
ভেক্টরের সবচেয়ে বড় সুবিধা হলো যে, এটি পুনঃব্যবহারযোগ্য এবং ইমিউটেবল, এবং একে একাধিক ক্লাসে ব্যবহার করা যায় যেটি কোডের পারফরম্যান্সের জন্য উপকারী।
উদাহরণ:
object VectorExample {
def main(args: Array[String]): Unit = {
val vector = Vector(1, 2, 3, 4, 5)
// অ্যাক্সেসিং প্রথম এলিমেন্ট
println(vector(0)) // Output: 1
// নতুন এলিমেন্ট যোগ করা
val newVector = vector :+ 6
println(newVector) // Output: Vector(1, 2, 3, 4, 5, 6)
// আপডেট করা
val updatedVector = vector.updated(0, 10)
println(updatedVector) // Output: Vector(10, 2, 3, 4, 5)
}
}এখানে:
Vector(1, 2, 3, 4, 5): একটি ভেক্টর তৈরি করা হয়েছে।vector(0): প্রথম ইনডেক্সের উপাদান অ্যাক্সেস করা হচ্ছে।: + 6: নতুন উপাদান ভেক্টরের শেষে যোগ করা হয়েছে।
ভেক্টরের সুবিধা:
- দ্রুত অ্যাক্সেস: ইনডেক্সিং এবং আপডেটিংয়ের জন্য দ্রুত।
- ইমিউটেবল: ভেক্টরের যেকোনো পরিবর্তন একটি নতুন ভেক্টর তৈরি করবে।
- সহজ অপারেশন: ভেক্টরে নতুন উপাদান যোগ করা, মুছে ফেলা, আপডেট করা সহজ।
ভেক্টরের ব্যবহার:
- ভেক্টর সাধারণত ব্যবহৃত হয় যখন একটি বড় ডাটা সিস্টেমে দ্রুত অ্যাক্সেস এবং পরিবর্তন প্রয়োজন।
২. স্ট্রিম (Stream)
স্ট্রিম স্কালার একটি lazy (আলস্যপূর্ণ) ডাটা স্ট্রাকচার। এটি একটি ইমিউটেবল ডাটা স্ট্রাকচার যা কেবলমাত্র প্রয়োজনে ইটারে করা হয়, অর্থাৎ স্ট্রিমের উপাদানগুলি তখনই গণনা করা হয় যখন সেগুলি এক্সেস করা হয়। স্ট্রিম ডাটা প্রক্রিয়ার জন্য কার্যকর, বিশেষ করে যখন আপনি একটি বড় ডাটা সেটের উপর বিভিন্ন অপারেশন করতে চান এবং সম্পূর্ণ ডাটাকে একসাথে মেমরিতে লোড করতে চান না।
স্ট্রিমের এক বিশেষ বৈশিষ্ট্য হল, lazy evaluation, যার মানে হলো স্ট্রিমে থাকা উপাদানগুলি তখনই প্রক্রিয়া হয় যখন সেগুলির প্রয়োজন পড়ে।
উদাহরণ:
object StreamExample {
def main(args: Array[String]): Unit = {
// Lazy Stream creation
val stream = Stream.from(1)
// Take first 5 elements from the stream
val firstFive = stream.take(5).toList
println(firstFive) // Output: List(1, 2, 3, 4, 5)
}
}এখানে:
Stream.from(1): একটি স্ট্রিম তৈরি করা হয়েছে যা ১ থেকে শুরু হবে এবং পরবর্তী সংখ্যা উৎপন্ন করবে।take(5): প্রথম ৫টি উপাদান নেওয়া হয়েছে।toList: স্ট্রিমকে একটি লিস্টে রূপান্তরিত করা হয়েছে।
স্ট্রিমের সুবিধা:
- Lazy Evaluation: স্ট্রিম কেবল তখনই উপাদানগুলির উপর কাজ করে যখন সেগুলি প্রয়োজন হয়।
- মেমরি সাশ্রয়ী: বড় ডাটা সেটের সাথে কাজ করার সময় স্ট্রিম কম মেমরি ব্যবহার করে, কারণ এটি একে একে উপাদান প্রক্রিয়া করে।
- ফাংশনাল অপারেশন: স্ট্রিমে বিভিন্ন ফাংশনাল অপারেশন যেমন map, filter, reduce সহজে করা যায়।
স্ট্রিমের ব্যবহার:
- স্ট্রিম সাধারণত ব্যবহৃত হয় যখন আপনি একটি বড় ডাটা সেটের উপাদানগুলো lazyভাবে প্রক্রিয়া করতে চান এবং সম্পূর্ণ ডাটা লোড না করেই কাজ করতে চান।
৩. ভেক্টর এবং স্ট্রিমের পার্থক্য
| বৈশিষ্ট্য | ভেক্টর (Vector) | স্ট্রিম (Stream) |
|---|---|---|
| ডাটা স্ট্রাকচার | অ্যারে-ভিত্তিক, ইমিউটেবল | Lazy, ইমিউটেবল |
| পারফরম্যান্স | দ্রুত অ্যাক্সেস, ইনডেক্সিং | Lazy evaluation, জেনারেটিভ |
| ব্যবহার | দ্রুত ইনডেক্সিং এবং আপডেটিং | বড় ডাটা সেটের উপর অপারেশন, lazy evaluation |
| অপারেশন | ইনডেক্সিং, যোগ করা, মুছে ফেলা | lazy অপারেশন, map, filter, reduce |
| ইমিউটেবল | হ্যাঁ | হ্যাঁ |
| Lazy Evaluation | না | হ্যাঁ |
৪. ভেক্টর এবং স্ট্রিমের প্রাসঙ্গিকতা
- ভেক্টর: যদি আপনার দ্রুত অ্যাক্সেস এবং ছোট আকারের ডাটা সেটের প্রক্রিয়া করতে হয়, তবে ভেক্টর ব্যবহার করা উপযুক্ত। এটি ব্যবহারকারী ইনপুট বা অ্যাক্সেসযোগ্য ডাটা স্টোরেজের জন্য উপযুক্ত।
- স্ট্রিম: যদি আপনার একটি বড় ডাটা সেটের উপর অপারেশন করতে হয় এবং আপনি lazy evaluation বা ফাংশনাল প্রোগ্রামিং করতে চান, তবে স্ট্রিম ব্যবহারের উপযুক্ত। এটি মেমরি সাশ্রয়ী এবং যখন পুরো ডাটা সিস্টেম প্রক্রিয়া করার প্রয়োজন নেই, তখন এটি কার্যকরী।
সারাংশ
- ভেক্টর (Vector) একটি ইমিউটেবল, অ্যারে-ভিত্তিক ডাটা স্ট্রাকচার যা দ্রুত অ্যাক্সেস এবং ইনডেক্সিং প্রদান করে।
- স্ট্রিম (Stream) একটি lazy ইমিউটেবল ডাটা স্ট্রাকচার যা কেবল তখনই ডাটা প্রক্রিয়া করে যখন এটি প্রয়োজন হয় এবং এটি বড় ডাটা সেটের জন্য কার্যকরী।
এগুলি স্কালার ফাংশনাল প্রোগ্রামিং এবং ফাংশনাল অপারেশন যেমন map, filter, reduce প্রক্রিয়ার ক্ষেত্রে খুবই সহায়ক।
স্কালা প্রোগ্রামিং ভাষায় কালেকশন API একটি অত্যন্ত শক্তিশালী বৈশিষ্ট্য যা ডাটা স্ট্রাকচার (যেমন লিস্ট, সেট, ম্যাপ, ভেক্টর, স্ট্রিম ইত্যাদি) ব্যবস্থাপনা, প্রসেসিং এবং অপারেশন করার জন্য ব্যবহৃত হয়। স্কালার কালেকশন API তে অনেক ধরনের ফাংশনাল এবং ইমিউটেবল কালেকশন রয়েছে যা খুবই কার্যকরী এবং স্কালার ফাংশনাল প্রোগ্রামিং কৌশলগুলির সাথে পুরোপুরি সঙ্গতিপূর্ণ।
স্কালা কালেকশন API Overview
স্কালার কালেকশন API দুটি প্রধান শ্রেণিতে বিভক্ত:
- Mutable Collections: যেগুলি মিউটেবল, অর্থাৎ এগুলির উপাদান পরিবর্তন করা যায়।
- Immutable Collections: যেগুলি ইমিউটেবল, অর্থাৎ একবার তৈরি হলে তাদের উপাদান পরিবর্তন করা যায় না।
স্কালা কালেকশন API ফাংশনাল প্রোগ্রামিংয়ের সুবিধা যেমন হাইয়ার অর্ডার ফাংশন (map, flatMap, filter, reduce ইত্যাদি) এবং ইমিউটেবল ডাটা স্ট্রাকচার প্রদান করে যা প্রোগ্রামিংকে আরও সুন্দর, কার্যকরী এবং দ্রুততর করে তোলে।
১. Immutable Collections
ইমিউটেবল কালেকশনগুলি একবার তৈরি হলে তাদের উপাদান পরিবর্তন করা যায় না। যখন আপনি একটি ইমিউটেবল কালেকশন পরিবর্তন করার চেষ্টা করবেন, তখন এটি নতুন একটি কালেকশন রিটার্ন করবে। স্কালায় ইমিউটেবল কালেকশনগুলির মধ্যে রয়েছে:
- List
- Set
- Map
- Vector
- Stream
১.১ List (ইমিউটেবল)
স্কালার List একটি অর্ডারড কালেকশন যা ডুপ্লিকেট উপাদান ধারণ করতে পারে।
val list = List(1, 2, 3, 4, 5)
println(list.map(x => x * 2)) // Output: List(2, 4, 6, 8, 10)এখানে:
mapফাংশনটি প্রতিটি উপাদানকে দ্বিগুণ করছে।
১.২ Set (ইমিউটেবল)
Set একটি কালেকশন যা অর্ডার্ড নয় এবং এতে ডুপ্লিকেট উপাদান থাকে না।
val set = Set(1, 2, 3, 4, 4, 5)
println(set) // Output: Set(1, 2, 3, 4, 5)এখানে:
- ডুপ্লিকেট উপাদানগুলো কেটে ফেলা হয়েছে।
১.৩ Map (ইমিউটেবল)
Map হল একটি কালেকশন যা কী-মান পেয়ার ধারণ করে। এটি সাধারণত ডিকশনারি বা ম্যাপের মতো কাজ করে।
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
println(map.keys) // Output: Set(a, b, c)
println(map.values) // Output: Iterable(1, 2, 3)এখানে:
keysফাংশনটি ম্যাপের সমস্ত কী (key) রিটার্ন করবে।valuesফাংশনটি ম্যাপের সমস্ত মান (values) রিটার্ন করবে।
১.৪ Vector (ইমিউটেবল)
Vector হল একটি দ্রুত অ্যাক্সেসযোগ্য এবং ইমিউটেবল কালেকশন।
val vector = Vector(1, 2, 3, 4)
println(vector) // Output: Vector(1, 2, 3, 4)এটি বড় ডাটা সেটের জন্য উপযুক্ত, যেখানে দ্রুত অ্যাক্সেস এবং পরিবর্তন দরকার।
১.৫ Stream (Lazy Evaluation)
Stream একটি বিশেষ ধরনের কালেকশন যা lazy evaluation ব্যবহার করে। এর মানে হল যে, যখনই কোনো উপাদান প্রয়োজন হয়, তখনই তা হিসাব করা হবে।
val stream = Stream.from(1)
println(stream.take(5).toList) // Output: List(1, 2, 3, 4, 5)এখানে:
Stream.from(1)একটি ইনফিনিট স্ট্রিম তৈরি করবে, এবংtake(5)প্রথম ৫টি উপাদান নেবে।
২. Mutable Collections
Mutable Collections-এ উপাদান পরিবর্তন বা ম্যানিপুলেট করা যায়। এই কালেকশনগুলির মধ্যে রয়েছে:
- ListBuffer
- ArrayBuffer
- HashSet
- HashMap
২.১ ListBuffer (Mutable)
এটি একটি পরিবর্তনযোগ্য List যা নতুন উপাদান যোগ বা মুছে ফেলা সম্ভব।
import scala.collection.mutable.ListBuffer
val listBuffer = ListBuffer(1, 2, 3, 4)
listBuffer += 5
println(listBuffer) // Output: ListBuffer(1, 2, 3, 4, 5)এখানে:
+=ব্যবহার করে নতুন উপাদান যুক্ত করা হচ্ছে।
২.২ ArrayBuffer (Mutable)
এটি একটি পরিবর্তনযোগ্য অ্যারে।
import scala.collection.mutable.ArrayBuffer
val arrayBuffer = ArrayBuffer(1, 2, 3)
arrayBuffer.append(4)
println(arrayBuffer) // Output: ArrayBuffer(1, 2, 3, 4)এখানে:
appendফাংশনটি নতুন উপাদান অ্যারে বাফারে যুক্ত করেছে।
২.৩ HashSet (Mutable)
HashSet হল একটি পরিবর্তনযোগ্য সেট, যেখানে উপাদানগুলি অর্ডারড না এবং ডুপ্লিকেট থাকে না।
import scala.collection.mutable.HashSet
val hashSet = HashSet(1, 2, 3)
hashSet += 4
println(hashSet) // Output: HashSet(1, 2, 3, 4)এখানে:
+=ফাংশনটি নতুন উপাদান যুক্ত করছে।
২.৪ HashMap (Mutable)
HashMap একটি পরিবর্তনযোগ্য ম্যাপ যা কী-মান পেয়ার ধারণ করে।
import scala.collection.mutable.HashMap
val hashMap = HashMap("a" -> 1, "b" -> 2)
hashMap("c") = 3
println(hashMap) // Output: HashMap(a -> 1, b -> 2, c -> 3)এখানে:
("c") = 3সিনট্যাক্সটি একটি নতুন কী-মান পেয়ার যোগ করেছে।
৩. কিছু গুরুত্বপূর্ণ কালেকশন ফাংশন
স্কালার কালেকশনগুলির ওপর অনেক শক্তিশালী ফাংশনাল অপারেশন করা যায়, যেমন:
- map: কালেকশনের প্রতিটি উপাদানে একটি ফাংশন প্রয়োগ করে নতুন একটি কালেকশন রিটার্ন করা।
- filter: শর্তের ভিত্তিতে উপাদানগুলো ফিল্টার করা।
- reduce: একটি একক মানে উপাদানগুলো কম্পাইল করা।
- flatMap: একটি কালেকশনের প্রতি উপাদান থেকে একাধিক উপাদান তৈরি করা।
উদাহরণ:
val numbers = List(1, 2, 3, 4, 5)
// map উদাহরণ
val doubled = numbers.map(x => x * 2)
println(doubled) // Output: List(2, 4, 6, 8, 10)
// filter উদাহরণ
val evenNumbers = numbers.filter(x => x % 2 == 0)
println(evenNumbers) // Output: List(2, 4)
// reduce উদাহরণ
val sum = numbers.reduce((a, b) => a + b)
println(sum) // Output: 15সারাংশ
স্কালা কালেকশন API অত্যন্ত শক্তিশালী এবং অনেক ধরনের ইমিউটেবল এবং মিউটেবল ডাটা স্ট্রাকচার সরবরাহ করে, যা ডেটার প্রক্রিয়াকরণ, ফিল্টারিং, এবং পরিবর্তন করার জন্য ব্যবহৃত হয়। স্কালার কালেকশন API তে ফাংশনাল প্রোগ্রামিং কৌশল যেমন map, filter, reduce, flatMap ইত্যাদি ব্যবহার করা যায়, যা কোডকে আরও পরিষ্কার এবং কার্যকরী করে তোলে।
Read more