Java Functional Programming এ Optional একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা null safety নিশ্চিত করতে এবং কোডে null চেকিং সহজ করার জন্য ব্যবহৃত হয়। Optional জাভা 8 তে java.util প্যাকেজে অন্তর্ভুক্ত করা হয়েছে এবং এটি একটি ফাংশনাল পারাডাইমের অংশ হিসেবে কাজ করে, যেখানে অপশনাল মান (optional value) লজিক্যালভাবে পরিচালিত হয়।
Optional এক ধরনের container object যা null অথবা non-null মান ধারণ করতে পারে। এটি ফাংশনাল প্রোগ্রামিং এর সাথে কাজ করে, যেখানে null ভ্যালু থেকে সৃষ্ট সমস্যা (যেমন NullPointerException) কমানো এবং কোডের রিডেবিলিটি ও সেফটি বৃদ্ধি করা হয়।
১. Optional কি?
Optional একটি container object যা কোনো মান ধারণ করতে পারে অথবা এটি খালি (empty) থাকতে পারে, অর্থাৎ এটি null থাকতে পারে। এর মূল উদ্দেশ্য হলো null চেক করার প্রয়োজনীয়তা কমানো এবং কোডের মধ্যে null সম্পর্কিত ব্যতিক্রম (exceptions) কমানো।
Optional এর মূল সুবিধা হলো এটি আপনাকে একটি ভ্যালু ফেরত দেওয়ার পরিবর্তে একটি container প্রদান করে, যা আপনি ফাংশনাল স্টাইলে ব্যবহার করতে পারেন।
২. Optional এর Sintax
Optional ব্যবহার করতে, আপনি সাধারণত Optional.of(), Optional.empty(), বা Optional.ofNullable() মেথডগুলো ব্যবহার করেন।
Optional<Type> optionalValue = Optional.of(value);
Optional<Type> emptyValue = Optional.empty();
Optional<Type> nullableValue = Optional.ofNullable(value);
এখানে:
Optional.of(T value)একটিOptionalতৈরি করে যা একটি non-null মান ধারণ করে।Optional.empty()একটি খালিOptional(যার মধ্যে কোনো মান নেই) তৈরি করে।Optional.ofNullable(T value)একটিOptionalতৈরি করে যা একটি nullable মান ধারণ করে, অর্থাৎ, এটি null অথবা non-null হতে পারে।
৩. Optional এর মূল কার্যাবলী
Optional অনেক ধরনের মেথড সরবরাহ করে যেগুলোর মাধ্যমে আপনি null মানের সমস্যা এড়িয়ে কার্যকরীভাবে কাজ করতে পারেন।
৩.১ isPresent() এবং ifPresent()
isPresent(): এটি যাচাই করে যেOptionalঅবজেক্টে কোনো মান আছে কি না।ifPresent(): এটি একটি consumer ফাংশন গ্রহণ করে, যা শুধুমাত্র তখন কার্যকর হবে যখনOptionalঅবজেক্টে একটি মান উপস্থিত থাকবে।
উদাহরণ:
Optional<String> name = Optional.of("John");
// Checking if value is present
if (name.isPresent()) {
System.out.println("Name: " + name.get());
}
// Using ifPresent to execute a function if a value is present
name.ifPresent(n -> System.out.println("Name: " + n));
৩.২ get()
get() মেথডটি Optional অবজেক্ট থেকে মান বের করে, তবে এটি যদি খালি থাকে (অর্থাৎ, null থাকে), তবে এটি একটি NoSuchElementException ছুঁড়ে ফেলে।
Optional<String> name = Optional.of("John");
System.out.println(name.get()); // Output: John
৩.৩ orElse() এবং orElseGet()
orElse(T other): এটি একটি ডিফল্ট মান প্রদান করে যদিOptionalখালি থাকে।orElseGet(Supplier<? extends T> other): এটি একটি supplier ফাংশন গ্রহণ করে যা ডিফল্ট মান প্রদান করবে।
উদাহরণ:
Optional<String> name = Optional.empty();
// If name is not present, use default value
String defaultName = name.orElse("Default Name");
System.out.println(defaultName); // Output: Default Name
// Using orElseGet with a Supplier
String defaultNameWithSupplier = name.orElseGet(() -> "Supplier Default Name");
System.out.println(defaultNameWithSupplier); // Output: Supplier Default Name
৩.৪ map() এবং flatMap()
map(): এটিOptionalএর মধ্যে থাকা মানের উপর একটি ফাংশন প্রয়োগ করে এবং একটি নতুনOptionalফেরত দেয়।flatMap(): এটিmap()এর মতো, তবে এটি একটি ফ্ল্যাটOptionalফেরত দেয় (যদি ফাংশনটি আরেকটিOptionalফেরত দেয়)।
উদাহরণ:
Optional<String> name = Optional.of("John");
// Using map to transform the value inside Optional
Optional<String> upperName = name.map(n -> n.toUpperCase());
System.out.println(upperName.get()); // Output: JOHN
// Using flatMap
Optional<Optional<String>> nestedName = Optional.of(Optional.of("Jane"));
Optional<String> flatName = nestedName.flatMap(n -> n);
System.out.println(flatName.get()); // Output: Jane
৩.৫ filter()
filter() মেথডটি Optional অবজেক্টের মানের উপর একটি শর্ত প্রয়োগ করে এবং একটি নতুন Optional ফেরত দেয় যদি শর্তটি পূর্ণ হয়।
উদাহরণ:
Optional<String> name = Optional.of("John");
// Filtering based on condition
Optional<String> filteredName = name.filter(n -> n.startsWith("J"));
System.out.println(filteredName.get()); // Output: John
Optional<String> emptyName = name.filter(n -> n.startsWith("X"));
System.out.println(emptyName.isPresent()); // Output: false
৪. Optional এর প্রয়োজনীয়তা
৪.১ Null Pointer Exception (NPE) রোধ
একটি বড় সমস্যা যা জাভা প্রোগ্রামিং এ ঘটতে পারে তা হল NullPointerException (NPE)। Optional ব্যবহার করলে null এর পরিবর্তে একটি সুস্পষ্ট উপায় তৈরি হয়, যা এক্সপ্রেসিভ এবং নিরাপদ থাকে।
উদাহরণ:
String name = null;
System.out.println(name.length()); // Throws NullPointerException
এই সমস্যা সমাধানে Optional ব্যবহার করা হয়:
Optional<String> name = Optional.ofNullable(null);
name.ifPresent(n -> System.out.println(n.length())); // Does not throw exception
৪.২ Functional Style of Programming
Optional ফাংশনাল প্রোগ্রামিং এ সহায়তা করে, যেখানে আপনি লম্বা null চেকিং কোডের বদলে stream-based পদ্ধতিতে কাজ করতে পারেন। Optional আপনার কোডকে map, flatMap, filter ইত্যাদি ফাংশনাল অপারেশন করতে সহায়ক করে।
৪.৩ Readable and Clean Code
Optional ব্যবহার করলে কোড আরও পরিষ্কার এবং রিডেবল হয়, কারণ এতে null এর জন্য বিশেষভাবে কিছু নির্দিষ্ট চেক করা হয়, যা সাধারণত কোডে দেখা যায় না।
৫. Optional এর কিছু সাধারন ব্যবহার
Return Type হিসেবে Optional:
- যখন একটি ফাংশন এমন কোনো ভ্যালু রিটার্ন করে যা null হতে পারে, তখন
Optionalফেরত দেয়ার মাধ্যমে null এর সমস্যা থেকে মুক্তি পাওয়া যায়।
public Optional<String> findNameById(int id) { if (id == 1) { return Optional.of("John"); } else { return Optional.empty(); } }- যখন একটি ফাংশন এমন কোনো ভ্যালু রিটার্ন করে যা null হতে পারে, তখন
Functional Chaining:
Optionalব্যবহার করে আপনি ফাংশনাল চেইনিং করতে পারেন, যেমন map/filter এবং পরেorElse()ব্যবহার করতে পারেন।
Optional<String> name = Optional.of("Java"); String result = name.filter(n -> n.length() > 3) .map(String::toUpperCase) .orElse("Default"); System.out.println(result); // Output: JAVA
সারাংশ
Optional হল একটি শক্তিশালী ধারণা যা ফাংশনাল প্রোগ্রামিং স্টাইলে Java কোড লিখতে সহায়তা করে। এটি null চেকিং সহজ করে এবং কোডে null সম্পর্কিত সমস্যা (যেমন NullPointerException) রোধ করতে সহায়তা করে। Optional ফাংশনাল প্রোগ্রামিং ধারণার একটি অপরিহার্য অংশ, যা map, filter, flatMap, ifPresent, orElse ইত্যাদি ফাংশনাল অপারেশন সমর্থন করে। এটি কোডকে আরও রিডেবল, সেফ এবং স্কেলেবল করে তোলে।
Read more