Streams স্কালাতে এমন একটি ধারণা, যা একটি ডেটা স্ট্রাকচার (যেমন, List, Set, Map) এর উপাদানগুলির উপরে প্রসেসিং করার জন্য ব্যবহৃত হয়। স্কালার Streams সাধারণত Lazy Evaluation (অলস মূল্যায়ন) এবং Functional Programming প্রিন্সিপাল অনুসরণ করে, যা আপনাকে বড় ডেটাসেটগুলির ওপর কার্যকরী এবং স্মার্টভাবে কাজ করতে সাহায্য করে।
Streams-এর মূল উদ্দেশ্য হল একটি ডেটা সিকোয়েন্সের উপর এক বা একাধিক ট্রান্সফরমেশন এবং অপারেশন সম্পন্ন করা, অলসভাবে, অর্থাৎ যখন আপনি পরবর্তী উপাদানটি পেতে চান তখনই সেটা হিসাব করা হয়। এর ফলে, ডেটা পুরোপুরি লোড না করেও আপনি একে একে ডেটা প্রসেস করতে পারেন।
Streams এর বৈশিষ্ট্য
- Lazy Evaluation (অলস মূল্যায়ন):
Streams কালেকশনের উপাদানগুলো প্রক্রিয়া করার জন্য Lazy Evaluation ব্যবহার করে। মানে, যতক্ষণ না পর্যন্ত আপনি একটি নির্দিষ্ট অপারেশন প্রয়োগ না করেন, ততক্ষণ পর্যন্ত ডেটা প্রসেসিং করা হয় না। - Composability (কোম্পোজেবিলিটি):
স্ট্রীমে একাধিক অপারেশন (যেমনmap,filter,reduce) একে একে জড়িত হতে পারে, এবং এগুলির ফলাফল একটি স্ট্রীমে পরিবর্তিত হয়। - Infinite Data Handling (অসীম ডেটা পরিচালনা):
স্ট্রীম ইনফিনিট ডেটাসেটও প্রক্রিয়া করতে পারে কারণ এটি Lazy (অলস) অপারেশন অনুসরণ করে, যা ডেটা প্রয়োজন না হওয়া পর্যন্ত ডেটা লোড করে না। - Parallel Processing (প্যারালাল প্রসেসিং):
স্ট্রীম প্যারালাল প্রসেসিং সমর্থন করে, যার মাধ্যমে আপনি বড় ডেটাসেটের উপর একাধিক কোর বা থ্রেড ব্যবহার করে দ্রুত কাজ করতে পারেন।
Streams ব্যবহার করে Large Data Sets পরিচালনা
Large Data Sets বা বড় ডেটাসেটের সাথে কাজ করার সময়, একে একে ডেটা লোড করা এবং প্রক্রিয়া করা গুরুত্বপূর্ণ, কারণ সম্পূর্ণ ডেটা একবারে মেমোরিতে লোড করলে সিস্টেমের কর্মক্ষমতা ক্ষতিগ্রস্ত হতে পারে। Streams বড় ডেটাসেটের উপরে কার্যকরীভাবে কাজ করার জন্য উপযুক্ত একটি পদ্ধতি।
উদাহরণ ১: Basic Stream Example
val largeDataSet = (1 to 1000000).toList
// Lazy processing: Only the elements you need are processed
val filtered = largeDataSet.view.filter(_ % 2 == 0).map(_ * 2).toList
println(filtered.take(10)) // First 10 resultsএখানে, view ব্যবহার করা হয়েছে, যা স্ট্রীমকে অলসভাবে প্রসেস করে। filter এবং map অপারেশনগুলো শুধুমাত্র প্রয়োজন হলে চালানো হবে, পুরো ডেটাসেট একবারে লোড করা হবে না।
উদাহরণ ২: Parallel Stream Example
val largeDataSet = (1 to 1000000).toList
// Parallel processing for large data set
val filteredParallel = largeDataSet.par.filter(_ % 2 == 0).map(_ * 2).toList
println(filteredParallel.take(10)) // First 10 resultsএখানে, par ব্যবহার করা হয়েছে, যা স্ট্রীমের উপাদানগুলিকে একাধিক থ্রেডে প্রসেস করতে সক্ষম করে, যার ফলে বড় ডেটাসেটের প্রক্রিয়া দ্রুত হয়।
উদাহরণ ৩: Infinite Stream Example
স্কালাতে স্ট্রীম ইনফিনিট ডেটাসেটও প্রসেস করতে পারে:
// Infinite Stream example
val infiniteStream = Stream.from(1)
val first10EvenNumbers = infiniteStream.filter(_ % 2 == 0).take(10).toList
println(first10EvenNumbers) // List of first 10 even numbersএখানে, Stream.from(1) একটি ইনফিনিট স্ট্রীম তৈরি করে যা 1 থেকে শুরু হয়ে অবিরত বৃদ্ধি পায়। take(10) মেথডটি প্রথম 10টি উপাদান সংগ্রহ করে।
Streams এর সুবিধা
- দ্রুত প্রক্রিয়া:
স্ট্রীমের সাহায্যে আপনি বড় ডেটাসেটের উপরে কার্যকরীভাবে কাজ করতে পারেন, কারণ এটি Lazy Evaluation অনুসরণ করে এবং শুধুমাত্র প্রয়োজনীয় ডেটা প্রক্রিয়া করে। - প্যারালাল প্রসেসিং:
স্ট্রীমের প্যারালাল প্রসেসিং ব্যবহারের মাধ্যমে আপনি বড় ডেটাসেটের উপর একাধিক থ্রেড ব্যবহার করতে পারেন, যা পারফরম্যান্স উন্নত করতে সহায়ক। - নমনীয়তা এবং ফাংশনাল অপারেশন:
স্ট্রীম সহজেই map, filter, reduce, flatMap ইত্যাদি ফাংশনাল অপারেশন সমর্থন করে, যা ডেটা ট্রান্সফর্মেশন এবং ফিল্টারিং আরো সহজ এবং কার্যকরী করে। - ইনফিনিট ডেটা প্রক্রিয়া:
স্ট্রীম ইনফিনিট ডেটাসেট প্রক্রিয়া করতে সক্ষম, কারণ এটি শুধুমাত্র প্রয়োজনীয় ডেটা লোড করে এবং প্রক্রিয়া করে।
সারাংশ
Streams বড় ডেটাসেট পরিচালনা করার জন্য একটি শক্তিশালী পদ্ধতি যা Lazy Evaluation ব্যবহার করে। এটি ডেটাকে একে একে প্রক্রিয়া করতে সাহায্য করে এবং মেমরি ব্যবহারের দক্ষতা বৃদ্ধি করে। স্ট্রীম প্যারালাল প্রসেসিং সমর্থন করে এবং ইনফিনিট ডেটা প্রক্রিয়া করতে সক্ষম, যা বড় ডেটাসেটের সাথে কাজ করার ক্ষেত্রে অনেক সুবিধা দেয়। স্ট্রীমের মাধ্যমে আপনি দ্রুত এবং কার্যকরীভাবে ডেটা প্রক্রিয়া করতে পারেন, যা স্কালার ফাংশনাল প্রোগ্রামিং এর শক্তি এবং নমনীয়তা বাড়ায়।
Read more