1. Overview
In this tutorial, You will learn in-depth about Java 8 Optional Class methods and its usages.
Optional class is added to the java.util package. The intention of introducing this class in java 8 is mainly to check whether the value is present in the object or it is absent.
The object is to hold the set of values that means it contains the real values. So, such kind of object is called a Container.
The container object may contain a null or non-null value in it.
2. Optional Advantages
Before using Optional class methods you should know what are the benefits that you are going to get from it.
2.1 Completely you can avoid the null checks in the application and no need to write the utility methods
2.2 Zero NullPointerExceptions at runtime.
2.3 Code becomes cleaner and more readable
2.4 Say goodbye to boilerplate coding
2.5 Avoid third party api’s such as Apache Commons API ObjectsUtils
3. Optional Main Methods
The Optional class has many methods but only two methods are most used in the coding. Those two are isPresent() and get() methods.
isPresent() returns true if the optional has non-null values, otherwise false.
get() returns the actual value from Optional object. If optional has null value means it is empty. In such a case, NoSuchElementException is thrown.
Sample Example:
package com.oraclejavacertified.blogspot.java8.base64;
package com.oraclejavacertified.blogspot.java8.optional;
import java.util.Optional;
public class OptionalGetExample {
public static void main(String[] args) {
// Creating non null optional object.
Optional<String> optional= Optional.of("hello");
// checking value present in the optional or not.
if(optional.isPresent()){
String value = optional.get();
System.out.println("Optional value : "+value);
} else {
// if optional has no value
System.out.println("Optional has no value");
}
}
}
Output:
package com.oraclejavacertified.blogspot.java8.base64;
Optional value : hello
4. Optional Constructors and Creating Optional Objects
Optional is a final class and it has two private constructors as below. These two constructors can not be accessed because these are declared as private.
private Optional() {
this.value = null;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
So, now the question is how to create the Optional object with a non-null value and null value?
Answer: Optional class is added with static methods that help in creating Optional Objects for the given values. Optional object creation static methods are below with syntax.
static <T> Optional<T> empty(): Returns an empty Optional instance.
static <T> Optional<T> of(T value): Returns an Optional with the specified present non-null value.
the empty() method creates an empty stream with null value whereas. of() method creates Optional object with non-null value.
Example to create Optional objects:
import java.util.Optional;
public class OptionalObjectCreationExample {
public static void main(String[] args) {
// creating an empty optional object
Optional<Void> emptyOptional = Optional.empty();
// checking if the optional is empty or not
System.out.println(" Is optional is empty : " + emptyOptional.isEmpty());
// Creating String type Optional
Optional<String> stringOptional = Optional.of("Hello");
if (stringOptional.isPresent()) {
System.out.println("Getting value from stringOptional : " + stringOptional.get());
}
// Integer type optional
Optional<Integer> intOptionbal = Optional.of(1244);
System.out.println("Integer Optional: " + intOptionbal.get());
// Passing null to of() method.
Optional.of(null);
}
}
Output:
Is optional is empty : true
Getting value from stringOptional : Hello
Integer Optional: 1244
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.oraclejavacertified.blogspot.java8.optional.OptionalObjectCreationExample.main(OptionalObjectCreationExample.java:26)
Optional of() and empty() methods are to create non-null and empty Optional objects using its static methods.
Non null value must be passed to of() method otherwise it will throw NullPointerException.
5. Optional ofNullable()
If you are expecting some null values then use the ofNullable() method.
By using this method, if we pass in a null reference, it doesn’t throw an exception but rather returns an empty Optional object.
import java.util.Optional;
public class OfNullableExample {
public static void main(String[] args) {
// Creating optional
Optional<String> ofNullable = Optional.ofNullable("Non null value");
String content = ofNullable.get();
System.out.println("Ofnullable value :" + content);
// passing null value
Optional nullOptional = Optional.ofNullable(null);
nullOptional.get();
}
}
Output:
Ofnullable value :Non null value
It is suggested to use the ofNullable() method rather than using of() and empty() method separately. Because it does uses internally both of() for nonnull value and empty() for a null value.
6. Checking Value Presence
If a method is returning an Optional object then you need to check that whether the Optional is having a value or not.
To check this, the Optional class has an isPresent() method which returns true if it has non-null value or false if it empty or null value.
import java.util.Optional;
public class OfNullableExample {
public static void main(String[] args) {
// Creating optional
Optional<String> optional = Optional.ofNullable("oraclejavacertified.blogspot.com");
System.out.println("Chceking if optional has value with isPresent() method");
System.out.println("isPresent value : "+optional.isPresent());
// empty optional
Optional<String> emptyOptional = Optional.ofNullable(null);
System.out.println("isPresent value for empty optional : "+emptyOptional.isPresent());
}
}
Output:
Chceking if optional has value with isPresent() method
isPresent value : true
isPresent value for empty optional : false
Java 11 api is added with a new method to check if optional isempty or not using isEmpty() method.
public class OptionalIsEmpty {
public static void main(String[] args) {
// Creating optional
Optional<String> optional = Optional.ofNullable("oraclejavacertified.blogspot.com");
System.out.println("Checking if optional has value with isEmpty() method");
System.out.println("isEmpty value : " + optional.isEmpty());
// empty optional
Optional<String> emptyOptional = Optional.ofNullable(null);
System.out.println("isPreisEmptysent value for empty optional : " + emptyOptional.isEmpty());
}
}
Output:
Checking if optional has value with isEmpty() method
isEmpty value : false
isPreisEmptysent value for empty optional : true
7. Optional ifPresent()
You can do the if and if-else conditions on Optional object using the ifPresent() method.
public void ifPresent(Consumer<? super T> consumer)
This method takes Consumer as a functional argument and its logic is only be executed if it has not null value.
ifPresent() is introduced mainly to avoid null pointer exception.
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class OptionalIfPresent {
public static void main(String[] args) {
System.out.println("Example 1 : ------ Optional string ------ ");
// Creating optional
Optional<String> optional = Optional.ofNullable("oraclejavacertified.blogspot.com");
// ifpresent syntax
optional.ifPresent(value -> System.out.println(value));
System.out.println("Example 2 : ------ Optional List of integers ------ ");
// Creating list of numbers
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// Passing lsit to optional
Optional<List<Integer>> numbersOfListOptional = Optional.ofNullable(list);
// cheeking with ifpresent
numbersOfListOptional.ifPresent(optionalList -> optionalList.forEach(v -> System.out.println(v)));
Optional empty = Optional.empty();
empty.ifPresent(valeu -> System.out.println("no value"));
}
}
Output:
Example 1 : ------ Optional string ------
oraclejavacertified.blogspot.com
Example 2 : ------ Optional List of integers ------
1
2
3
4
5
8. Optional Default Values – orElse()
If the Optional is created with empty() or ofNullable(null) then you will get empty optional.
If the optional is empty then you can still get the default value using orElse() method.
orElse() method takes the value as a type of original Optional caller.
public T orElse(T other)
orElse() Example:
public class OptionalOrElse {
public static void main(String[] args) {
Optional<String> o1 = Optional.ofNullable(null);
String value = o1.orElse("Default One");
System.out.println("Fetching the value from orElse() : "+value);
Optional<Integer> intOptional = Optional.empty();
int defaultValue = intOptional.orElse(15);
System.out.println("Int default value :"+defaultValue);
}
}
Output:
Fetching the value from orElse() : Default One
Int default value :15
9. Optional Default Values – orElseGet()
orElseGet() method is to get the alternate value if the Optional is empty or has a null value. This method takes the Supplier as an argument.
public T orElseGet(Supplier<? extends T> other)
orElseGet() Example:
public class OptionalOrElseGet {
public static void main(String[] args) {
Optional<String> o1 = Optional.ofNullable(null);
String value = o1.orElseGet(() -> "Default One from supplier");
System.out.println("Fetching the value from orElseGet() : " + value);
Optional<Integer> intOptional = Optional.of(134);
int defaultValue = intOptional.orElseGet(() -> 15);
System.out.println("orElseGet Int default value :" + defaultValue);
}
}
Output:
Fetching the value from orElseGet() : Default One from supplier
orElseGet Int default value :134
10. Differences Between orElse() and orElseGet() Methods
orElseGet() method looks similar to the orElse() method as seen in the above section but there is a little different and that is the most important in the large scale applications.
The main difference is orElse() method will be executed always whether source Optional has value or not whereas orElseGet() will be invoked if and only if source optiona is an empty or null value.
Look at the example below to understand clearly.
Creating a method to get the string as a return. This method will be called by both of these methods.
In the below example, taking the Optional with null value by both methods.
public class OptionalDiffOrElseGetVsorElse {
public static void main(String[] args) {
// Optional with null value
Optional<String> opt1 = Optional.ofNullable(null);
String orElseValue1 = opt1.orElse(getDefaultValue());
System.out.println("orElse() value : " + orElseValue1);
// Optional with null value
Optional<String> opt2 = Optional.ofNullable(null);
String orElseValue2 = opt2.orElseGet(() -> getDefaultValue());
System.out.println("orElseGet() value : " + orElseValue2);
}
public static String getDefaultValue() {
System.out.println("executing to get the default value");
return "I am here to get the default value";
}
}
Output:
executing to get the default value
orElse() value : I am here to get the default value
executing to get the default value
orElseGet() value : I am here to get the default value
Here, the source optional has null value so it called the default logic getDefaultValue() in both cases.
Letus see now Optional with values.
public class OptionalDiffOrElseGetVsorElse {
public static void main(String[] args) {
// Optional with null value
Optional<String> opt13 = Optional.ofNullable("123");
String orElseValue3 = opt13.orElse(getDefaultValue());
System.out.println("orElse() value : " + orElseValue3);
// Optional with null value
Optional<String> opt4 = Optional.ofNullable("789");
String orElseValue4 = opt4.orElseGet(() -> getDefaultValue());
System.out.println("orElseGet() value : " + orElseValue4);
}
public static String getDefaultValue() {
System.out.println("executing to get the default value");
return "I am here to get the default value";
}
}
Output:
executing to get the default value
orElse() value : 123
orElseGet() value : 789
In this case, Both sources optional objects are created with the values which are not null. So, getDefaultValue() method should not be called as we expected but in the output, it printed the content from getDefaultValue() method from orElse() method.
11. Optional filter()
filter() method is used to filter the optional values based on the predicate condition.
public Optional<T> filter(Predicate<? super T> predicate)
Example:
An example to check the given number is even or odd. If the number is even then Optional will have an even number.
public class OptionalFilterExample {
public static void main(String[] args) {
// Creating optional
Optional<Integer> op = Optional.ofNullable(1234);
Optional<Integer> evenOrNot = op.filter(number -> number % 2 == 0);
if (evenOrNot.isEmpty()) {
System.out.println("Odd number");
} else {
System.out.println("Even number");
}
}
}
Output:
Even number
12. Optional.map() -Value Transformations
Optional map() isused to transform the optional into another form.
public class OptionalMapExample {
public static void main(String[] args) {
// Creating optional
Optional<String> op = Optional.ofNullable("Welcome reader");
Optional<String> mapOptional = op.map(value -> {
if (value.contains("Welcome")) {
return "Articles are good";
} else {
return "Welcome to oraclejavacertified.blogspot.com";
}
});
mapOptional.ifPresent(action -> System.out.println(action));
}
}
Output:
Articles are good
13. Optional.ifPresent()
Run the another logic if the optional value is present.
If a value is present, invoke the specified consumer with the value, otherwise do nothing.
public void ifPresent(Consumer<? super T> consumer)
Example to convert String to Integer using map() and ifPresent()
public class OptionalIfPresentExample {
public static void main(String[] args) {
// String value optional
Optional<String> string = Optional.ofNullable("12345");
// converting string to number
Optional<Integer> numberOptional = string.map(value -> Integer.parseInt(value));
// printing the number using ifPresent()
numberOptional.ifPresent(newValue -> System.out.println(newValue));
}
}
Output:
12345
14. Optional.flatMap()
flatMap(): If a value is present, apply the provided Optional-bearing mapping function to it, return that result, otherwise return an empty Optional.
It removes all nested Optional objects and just gets the value from it.
public class OptionalflatmapExample {
public static void main(String[] args) {
Optional<String> optional1 = Optional.of("Hello Java 8 Optional");
Optional<Optional<String>> optional2 = Optional.of(optional1);
System.out.println("Optional2 value : " + optional2);
Optional<String> output = optional2.flatMap(value -> value.map(String::toLowerCase));
System.out.println("output value : " + output);
}
}
Output:
Optional2 value : Optional[Optional[Hello Java 8]]
output value : Optional[hello java 8]
15. Optional orElseThrow()
Optional API added a new way to throw the exception if the value not present in the optional object.
orElseThrow() looks as similar to the orElse() and orElseGet() pattern.
orElseThrow() returns a value from the optional else throws the. exception saying “java.util.NoSuchElementException: No value present“.
Syntax:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
throws X extends Throwable
orElseThrow() Example:
public class OptionalOrElseThrowExample {
public static void main(String[] args) {
// orElseThrow() example
String blank = Optional.ofNullable("").orElseThrow();
System.out.println(blank);
String value = null;
String blank2 = Optional.ofNullable(value).orElseThrow();
System.out.println(blank2);
}
}
Output:
Exception in thread "main" java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.orElseThrow(Optional.java:382)
at com.oraclejavacertified.blogspot.java8.optional.OptionalOrElseThrowExample.main(OptionalOrElseThrowExample.java:13)
orElseThrow() Custom Exception Example:
public class OptionalOrElseThrowCustomExExample {
public static void main(String[] args) throws CustomException {
// orElseThrow() runtime IllegalArgumentException example
String nullValue = null;
String blank = Optional.ofNullable(nullValue).orElseThrow(IllegalArgumentException::new);
System.out.println(blank);
// throwing checked exception
String value = null;
String blank2 = Optional.ofNullable(value).orElseThrow(CustomException::new);
System.out.println(blank2);
}
}
class CustomException extends Exception {
public CustomException() {
}
}
This will produce the runtime exception and here used the method reference concept added in java 8.
16. Optional New Methods in Newer JDK’s
Optional api is added with new api methods in java 9, java 10, and java 11 versions as below.
Java 9:
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction): If a value is present, performs the given action with the value, otherwise performs the given empty-based action.
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier): If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function.
public Stream<T> stream(): If a value is present, returns a sequential Stream containing only that value, otherwise returns an empty Stream.
Java 10:
public T orElseThrow(): If a value is present, returns the value, otherwise throws NoSuchElementException.
Java 11:
public boolean isEmpty(): If a value is not present, returns true, otherwise false.
0 comments:
Post a Comment