Java 8 - Optional
In this blog, I’ll discuss about Optional class which was introduced in JDK8 under java.util.package. Optional class is used to represent a value is present or absent.With Optional class, developers have to less worry about NullPointerException and can work on neat and clean code. It contains at most one value.
Advantages:
· No need to check for null
· No more NullPointerException at runtime
Public final class Optional<T> extends Object {Let’s understand all its usage with the help of example
}
1. Optional.empty()
To create an empty Optional object we simply need to write
// How to
create empty Optional
Optional<String> optional = Optional.empty();
System.out.println("1. Optional: " + optional);Output:
1. Optional: Optional.empty
2. isPresent()
You can also check whether any value present in Optional or not
System.out.println("2. Optional: " + optional.isPresent());
Output:
2. Optional: false
3. Of() method
We can also use Static Of method to create an Optional Object.
//Can
create Optional using Static Of method
Optional<String> name = Optional.of("WaheedTechblog.com");
System.out.println("3. Name: " + name.toString());
Output:
3.
Name: Optional[WaheedTechblog.com]
Note: Make sure you are not passing any null value to Of() method else it would throw a NullPointer Exception.
Optional<String>
nullValue = Optional.of(null);
System.out.println("4. Name: " + nullValue.toString());
Output:
Exception in
thread "main" java.lang.NullPointerException
at
java.base/java.util.Objects.requireNonNull(Objects.java:221)
at
java.base/java.util.Optional.<init>(Optional.java:107)
at java.base/java.util.Optional.of(Optional.java:120)
at
com.waheedtechblog.optional.OptionalExample.main(OptionalExample.java:20)
4. OfNullable()
If you are not sure about the object you must use OfNullable API.
//Can accept
NUll value as well
Optional<String> isNull = Optional.ofNullable("WaheedTechblog.com");
System.out.println("5. Name: " + isNull.toString());
Output:
5. Name: Optional[WaheedTechblog.com]
If we pass a null reference, it does not throw an exception but returns an empty Optional object.
5. isPresent()
We can use isPresent() method to check whether the Optional object is empty or contains some value.
Optional<String> isNull = Optional.ofNullable("WaheedTechblog.com");
//check
isNull object contains some value
if(isNull.isPresent()) {
System.out.println("6. Optional object contains some value: " + isNull.toString());
}
Output:
6. Optional object contains some value:
Optional[WaheedTechblog.com]
6. isEmpty()
Similarly , we can use isEmpty method to check whether the Optional object is empty or not
//Check
whether object is empty or not
Optional<String> nullValue = Optional.ofNullable(null);
if (nullValue.isEmpty()) {System.out.println("7. Is Optional empty? " + nullValue.toString());
}
Output:
7. Optional object contains
some value: Optional.empty
7. ifPresent()
It enables us to run some code if Optional Object is not empty. Most of the time, we normally do something like this in our application.
If(user != null) {Over here, we are performing some operation based on if condition. This approach is lengthy and there are chances to miss such null checks which can result in a NullPointerException at runtime.
String name = user.getName();
}
ifPresent() accepts Consumer functional Interface.
//Execute
if Optional object exist.
Optional<String> name = Optional.of("WaheedTechblog.com");
name.ifPresent(value -> System.out.println("8.
Length of name: " + value.length()));
Output:
8.
Length of name: 18
8. orElse()
We can use orElse() method to set some default value incase if Optional object is Empty.
//Set Default value if Object is empty
String nullString = null;
String
testOrElse = Optional.ofNullable(nullString).orElse("This is default value");
System.out.println("9.
Print testorElse value: " + testOrElse);
Output:
9.
Print testorElse value: This is default value
9. orElseGet()
This API is very similar to orElse() method except that instead of taking default value, you can pass Supplier functional interface which returns response based on some operation.
//Invoke Functional Interface if Optional Object is empty
String testOrElseGet = Optional.ofNullable(nullString).orElseGet(() -> "waheedtechblog");
System.out.println("10.
Print orElseGet value: " + testOrElseGet);
Output:
10. Print orElseGet value: waheedtechblog
Note: At the very first glance, it looks like orElse and orElseGet method are very similar and either one of them can be used to get the default value but this is not very true. There is a subtle but very important difference between the two.
Let’s understand this with Example
private String getDbConnection() {
System.out.println("13. Invoking Default fucntion");
return "Create db Connection";
}
// Checking the diff between orElse Vs orElseGet
String testOrElseDiff = Optional.ofNullable("waheedtechblog").orElse(optionalExample.getDbConnection());
System.out.println("11. Print testorElse value: " + testOrElseDiff);
String testOrElseGetDiff = Optional.ofNullable("waheedtechblog").orElseGet(optionalExample::getDbConnection);
System.out.println("12.
Print orElseGet value: " + testOrElseGetDiff);
Output:
13. Invoking Default fucntion
11. Print testorElse value: waheedtechblog
12.
Print orElseGet value: waheedtechblog
If you observe the output, you will realize that orElse() method is invoking getDBConnection() when the object is already present whereas orElseGet() method is not invoking the DB call.
So, I would suggest choose orElseGet over orElse as database query or any rest API call can cost to your application performance when there was no need of that.
10. orElseThrow()
Instead of calling any default method in case of Optional value not present, it throws an exception.
//Throw runtime exception if Optional value is not present
String orElseThrowTest = Optional.ofNullable(nullString).orElseThrow(RuntimeException::new);
Output:
Exception in thread "main" java.lang.RuntimeException
at
java.base/java.util.Optional.orElseThrow(Optional.java:408)
at com.waheedtechblog.optional.OptionalExample.main(OptionalExample.java:62)
11. get()
Get returns the value of Optional Object if not null or else throws no such element exception.
Optional<String> getTest = Optional.ofNullable("waheedtechblog");
System.out.println("15. GetTest value: " + getTest.get());
Output:
15. GetTest value:
waheedtechblog
12. Filter()
The concept of filter is very similar to stream API filter. It takes Predicate as an argument and returns an Optional object.
// filteration
on Optional
Optional<String> username = Optional.of("waheedtechblog");
boolean isLengthValid = username.filter(str -> str.length() > 5).isPresent();
System.out.println("16. is Length Valid: " + isLengthValid);
Output:
16. is Length Valid: true
13. map()
Using map, we can transform the Optional value.
// map
to perform operation on Optional
Optional<String> password = Optional.of("waheedtechblog");
String encodedPassword = password.map(str -> Base64.getEncoder().encodeToString(str.getBytes())).get();
System.out.println("17. Encoded Password: " + encodedPassword);
Output:
17. Encoded Password:
d2FoZWVkdGVjaGJsb2c=
We can also merge filter and map together to get the result.
//
first do validation and then operation on Optional object
String validatedEncodedPassword = password.filter(ps -> ps.length()
> 15) .map(str -> Base64.getEncoder().encodeToString(str.getBytes())).toString();
System.out.println("18. Validated Encoded Password: " + validatedEncodedPassword);
Output:
18. Validated Encoded Password: Optional.empty
Happy Coding…!!!