Java 8 Optional Tutorial With Examples
A quick and in-depth tutorial to Optional API in java 8. Exploring various types of examples to understand the right usage.
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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.javaprogramto.java8.base64; package com.javaprogramto.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:
1 2 | package com.javaprogramto.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.
1 2 3 4 5 6 7 | 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.
1 2 | 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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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:
1 2 3 4 5 6 7 8 | 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.javaprogramto.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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | 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:
1 | 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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | import java.util.Optional; public class OfNullableExample { public static void main(String[] args) { // Creating optional Optional<String> optional = Optional.ofNullable( "javaprogramto.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:
1 2 3 | 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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | public class OptionalIsEmpty { public static void main(String[] args) { // Creating optional Optional<String> optional = Optional.ofNullable( "javaprogramto.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:
1 2 3 | 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.
1 | 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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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( "javaprogramto.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:
1 2 3 4 5 6 7 8 | Example 1 : ------ Optional string ------ javaprogramto.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.
1 | public T orElse(T other) |
orElse() Example:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | 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:
1 2 | 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.
1 | public T orElseGet(Supplier<? extends T> other) |
orElseGet() Example:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | 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:
1 2 | 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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | 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:
1 2 3 4 | 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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | 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:
1 2 3 | 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.
1 | 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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | 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:
1 | Even number |
12. Optional.map() -Value Transformations
Optional map() isused to transform the optional into another form.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | 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 javaprogramto.com" ; } }); mapOptional.ifPresent(action -> System.out.println(action)); } } |
Output:
1 | 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.
1 | public void ifPresent(Consumer<? super T> consumer) |
Example to convert String to Integer using map() and ifPresent()
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | 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:
1 | 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.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | 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:
1 2 | 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:
1 2 | public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X extends Throwable |
orElseThrow() Example:
01 02 03 04 05 06 07 08 09 10 11 12 13 | 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:
1 2 3 | Exception in thread "main" java.util.NoSuchElementException: No value present at java.base/java.util.Optional.orElseThrow(Optional.java: 382 ) at com.javaprogramto.java8.optional.OptionalOrElseThrowExample.main(OptionalOrElseThrowExample.java: 13 ) |
orElseThrow() Custom Exception Example:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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.
17. Conclusion
In this article, you’ve seen all the methods of Optional class in Java 8 with example programs, how to work with the null pointer exception in java 8 to avoid manual errors. Finally, we have shown what are the new methods added after JDK 8.
As usual, all of these example programs are over GitHub.
Published on Java Code Geeks with permission by Venkatesh Nukala, partner at our JCG program. See the original article here: Java 8 Optional Tutorial With Examples Opinions expressed by Java Code Geeks contributors are their own. |