ল্যাম্বডা এবং স্ট্রিমস (Lambdas & Streams)
ল্যাম্বডাস — ফাংশনের ভ্যালু হিসেবে কাজ করা (Lambdas — Functions as Values)
জাভা ৮ আসার আগে, যদি আপনি কোনো মেথডে সে কীভাবে কাজ করবে তা পাঠাতে চাইতেন, তবে আপনাকে পুরো একটি ক্লাস তৈরি করতে হতো। এটি অনেকটা একটি স্টিকি নোটের (sticky note) কাজ মেটানোর জন্য আস্ত একটা চিঠির পাতা লিখে ফেলার মতো। ল্যাম্বডাস (Lambdas) হলো সেই ছোট স্টিকি নোটের মতোই — অতি ক্ষুদ্র, নামহীন বা অ্যাননিমাস ফাংশন (anonymous functions), যাদের সহজে এক জায়গা থেকে আরেক জায়গায় পাঠানো যায়।
এর লেখার নিয়ম বা সিনট্যাক্স (syntax) বেশ সহজ: (parameters) -> expression
কিছু উদাহরণ:
(a, b) -> a + b— দুটি ভ্যালু গ্রহণ করে এবং তাদের যোগফল ফেরত দেয় বা রিটার্ন করে(s) -> s.length()— একটি স্ট্রিং গ্রহণ করে এবং তার দৈর্ঘ্য (length) ফেরত দেয়() -> System.out.println("Hello!")— কিছুই গ্রহণ করে না, শুধু hello প্রিন্ট করে
ল্যাম্বডা ফাংশনাল ইন্টারফেসগুলোর (functional interfaces) সাথে কাজ করে — এগুলো হলো এমন সব ইন্টারফেস, যাদের ঠিক একটি মাত্র অ্যাবস্ট্রাক্ট মেথড (abstract method) থাকে। জাভা আমাদের আগে থেকেই তৈরি করে রাখা এমন অনেকগুলো ফাংশনাল ইন্টারফেস দেয়। যেমন: Predicate (পরীক্ষা করার জন্য), Function (রূপান্তর করার জন্য), Consumer (কাজ করার জন্য) এবং Comparator (তুলনা করার জন্য)।
ল্যাম্বডার ব্যাসিকস এবং ফাংশনাল ইন্টারফেস (Lambda Basics & Functional Interfaces)
স্ট্রিমস — পাইপলাইনের মতো ডেটা প্রসেস করা (Streams — Processing Data Like a Pipeline)
একটি স্ট্রিমকে (stream) কারখানার কনভেয়ার বেল্টের (conveyor belt) মতো ভাবতে পারেন। ডেটার আইটেমগুলো এক প্রান্ত দিয়ে ঢোকে, এরপর বিভিন্ন স্টেশনের (যেমন ফিল্টার করা, ট্রান্সফর্ম বা রূপান্তর করা, সাজানো ইত্যাদি) ভেতর দিয়ে পার হয় এবং শেষ পর্যন্ত একটি সম্পূর্ণ বা ফিনিশড প্রোডাক্ট (finished product) হিসেবে অন্য প্রান্ত থেকে বেরিয়ে আসে।
স্ট্রিম যেকোনো মূল ডেটা বা আসল ডেটাকে পরিবর্তন করে না — তারা একটি নতুন ফলাফল তৈরি করে। তাছাড়া এরা খুবই অলস প্রকৃতির বা লেজি (lazy) হয়ে থাকে: যতক্ষণ না আপনি একটি টার্মিনাল অপারেশন (terminal operation) কল করছেন (যেমন: collect(), forEach(), অথবা count()), ততক্ষণ এরা কোনো কাজই শুরু করে না।
স্ট্রিমের সবচেয়ে পরিচিত কিছু অপারেশন বা কাজ:
filter()— যেসব আইটেম শর্তের সাথে মিলে যায়, কেবল তাদেরই রেখে দেয়map()— প্রতিটি আইটেমকে অন্য কোনো রূপে ট্রান্সফর্ম বা রূপান্তর করেsorted()— আইটেমগুলোকে সুন্দরভাবে সাজিয়ে রাখেreduce()— সবগুলো আইটেমকে একটি ফলাফলে একত্রিত করে ফেলেcollect()— ফলাফলগুলোকে একটি লিস্ট, সেট, অথবা অন্য কোনো কালেকশনের (collection) ভেতর জড়ো করে
ব্যাবহারিক ক্ষেত্রে স্ট্রিমস (Streams in Action)
স্ট্রিং এবং মেথড রেফারেন্সসহ স্ট্রিমস (Streams with Strings & Method References)
::) মূলত ছোট এবং সাধারণ ল্যাম্বডার একটি সংক্ষিপ্ত রূপ বা শর্টহ্যান্ড (shorthand) মাত্র। String::toUpperCase এবং s -> s.toUpperCase() আসলে একই জিনিস। যখন ল্যাম্বডা মাত্র একটি মেথডকে কল করে তখন এগুলো ব্যবহার করবেন — এতে আপনার কোডকে দেখতে স্বাভাবিক ইংরেজির মতো মনে হয়। যেমন System.out::println, Integer::parseInt, Math::max — এগুলো দেখতে একদম পরিষ্কার ও পরিচ্ছন্ন।