স্কালার ভেক্টর (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 প্রক্রিয়ার ক্ষেত্রে খুবই সহায়ক।
Read more