What is Functional Programming?
Functional Programming এমন একটি পদ্ধতি যেখানে—
- কী করতে হবে সেটায় ফোকাস করা হয়, কীভাবে করতে হবে তার চেয়ে বেশি
- ফাংশনকে ভ্যালু হিসেবে ব্যবহার করা যায়
- যতটা সম্ভব mutable state এড়ানো হয়
- side-effect কম বা নেই এমন কোড লেখা হয়
Java-তে Functional Programming সম্ভব হয়েছে মূলত:
- Lambda Expression
- Functional Interface
- Streams API
Java-তে Lambda কী?
Lambda expression হলো anonymous function লেখার একটি সংক্ষিপ্ত উপায়।
পুরোনো পদ্ধতি
Runnable r = new Runnable() {
public void run() {
System.out.println("Hello");
}
};
Lambda ব্যবহার করে
Runnable r = () -> System.out.println("Hello");
Lambda এর সিনট্যাক্স
(parameters) -> expression
(parameters) -> { statements }
উদাহরণ
(x, y) -> x + y
Functional Interface
Functional Interface হলো এমন interface যেখানে একটি মাত্র abstract method থাকে।
উদাহরণ:
- Runnable
- Comparator<T>
- Callable<V>
- Predicate<T>
- Function<T, R>
- Consumer<T>
- Supplier<T>
উদাহরণ
Predicate<Integer> isEven = n -> n % 2 == 0;
Java-তে Stream কী?
Stream হলো ডাটার একটি ধারাবাহিক প্রবাহ, যার উপর functional style-এ অপারেশন করা যায়।
Stream নিজে ডাটা সংরক্ষণ করে না, বরং collection থেকে ডাটা প্রসেস করে।
Traditional loop
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
for (int n : numbers) {
if (n % 2 == 0) {
System.out.println(n);
}
}
Stream ব্যবহার করে
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
Stream এর সাধারণ অপারেশন
Intermediate Operations (Lazy)
- filter()
- map()
- sorted()
- distinct()
- limit()
Terminal Operations
- forEach()
- collect()
- reduce()
- count()
- anyMatch(), allMatch()
বাস্তব উদাহরণ
"A" দিয়ে শুরু হওয়া নামগুলো uppercase করা
List<String> names = List.of("Alice", "Bob", "Andrew", "John");
List<String> result = names.stream()
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
.toList();
System.out.println(result);
কেন Java-তে Functional Programming ব্যবহার করবেন?
- কম কোড লিখতে হয়
- কোড বেশি পরিষ্কার ও readable হয়
- parallel processing সহজ
- আধুনিক CPU ভালোভাবে ব্যবহার করা যায়
- business logic পরিষ্কার থাকে
Parallel Stream
numbers.parallelStream()
.filter(n -> n > 10)
.forEach(System.out::println);
Imperative বনাম Functional
| Imperative | Functional |
|---|---|
| Loop ব্যবহার করে | Stream ব্যবহার করে |
| ভ্যারিয়েবল পরিবর্তন করে | mutable state এড়ায় |
| ধাপে ধাপে কাজ | declarative স্টাইল |
| parallel করা কঠিন | সহজে parallel করা যায় |
কখন ব্যবহার করবেন / করবেন না
ব্যবহার করুন যখন:
- Collection নিয়ে কাজ করবেন
- ডাটা filter / transform করবেন
- aggregation দরকার
এড়িয়ে চলুন যখন:
- অনেক side-effect আছে
- জটিল debugging দরকার
- খুব performance-critical tight loop