ZetCode

Java Optional

last modified August 22, 2026

In this article we learn how to create, inspect, transform, and read Optional values in Java.

Optional is a container object that may or may not contain a value. An Optional that contains no value is empty. We can test its state with isPresent or isEmpty, and process a present value with methods such as ifPresent, map, and orElse.

Optional is primarily intended as a return type for a method that may have no result. It does not eliminate null from Java, and it is usually not useful as a field or method parameter.

The Optional type makes the possibility of a missing result explicit in the method's return type. This encourages callers to choose what should happen when no value is available instead of accidentally dereferencing null.

The examples use Java 25's compact source-file syntax. With an earlier Java version, place the code inside a class and use a conventional public static void main(String[] args) method.

var empty = Optional.<String>empty();

We create an empty Optional with Optional.empty. The explicit type witness is needed here because the expression is assigned to var without another type context.

var word = Optional.of("falcon");

Optional.of is used when we are certain that the argument is not null. It throws NullPointerException if the argument is null.

var word = Optional.ofNullable(value);

Optional.ofNullable is used when the argument may be null. It creates an empty Optional for a null argument.

Simple example

In the following example, we have a simple example with Optional type.

Main.java
void main() {
 var words = Arrays.asList("rock", null, "mountain",
 null, "falcon", "sky");
 for (var value : words) {
 var word = Optional.ofNullable(value);
 word.ifPresent(System.out::println);
 }
}

We have a list of words; the list also contains null values. We wrap each value in an Optional and print only the values that are present.

Optional<String> word = Optional.ofNullable(words.get(i));

We know that we can get a null value from the list; therefore, we wrap each element in an Optional with Optional.ofNullable.

word.ifPresent(System.out::println);

We print the value only when the Optional is non-empty. The ifPresent method accepts the action to run for a present value.

In the following example, we have three methods that return an Optional type.

Main.java
void main() {
 if (getNullMessage().isPresent()) {
 System.out.println(getNullMessage().get());
 } else {
 System.out.println("n/a");
 }
 if (getEmptyMessage().isPresent()) {
 System.out.println(getEmptyMessage().get());
 } else {
 System.out.println("n/a");
 }
 if (getCustomMessage().isPresent()) {
 System.out.println(getCustomMessage().get());
 } else {
 System.out.println("n/a");
 }
}
Optional<String> getNullMessage() {
 return Optional.ofNullable(null);
}
Optional<String> getEmptyMessage() {
 return Optional.empty();
}
Optional<String> getCustomMessage() {
 return Optional.of("Hello there!");
}

The three methods return a null message, an empty message and a real message.

if (getNullMessage().isPresent()) {
 System.out.println(getNullMessage().get());
} else {
 System.out.println("n/a");
}

First, we check if the value returned by the method contains a value with isPresent. If true, we get the value with get. Otherwise we print "n/a" message.

Optional isEmpty

The isEmpty method returns true when the Optional contains no value. It is the logical opposite of isPresent.

Main.java
void main() {
 var words = Arrays.asList("rock", null, "mountain",
 null, "falcon", "sky");
 for (var value : words) {
 var word = Optional.ofNullable(value);
 if (word.isEmpty()) {
 System.out.println("n/a");
 } else {
 System.out.println(word.get());
 }
 }
}

In the example, we print n/a for empty values and the contained word for non-empty values. Although get is safe after the isEmpty check, orElse is usually clearer when a default value is available.

Optional orElse

The orElse method allows us to quickly return a value if it is not present.

Main.java
void main() {
 System.out.println(getNullMessage().orElse("n/a"));
 System.out.println(getEmptyMessage().orElse("n/a"));
 System.out.println(getCustomMessage().orElse("n/a"));
}
Optional<String> getNullMessage() {
 return Optional.ofNullable(null);
}
Optional<String> getEmptyMessage() {
 return Optional.empty();
}
Optional<String> getCustomMessage() {
 return Optional.of("Hello there!");
}

We managed to shorten the example a bit with orElse method.

The expression passed to orElse is evaluated even when the Optional already contains a value. Use orElseGet when the fallback is expensive to create or requires a method call; its supplier is evaluated only when the Optional is empty.

var word = Optional.of("falcon");
var result = word.orElseGet(() -> "n/a");

Use orElseThrow() when an empty Optional represents an error. It throws NoSuchElementException for an empty value. An overload also accepts a supplier for a more specific exception.

var word = Optional.of("falcon").orElseThrow();

Optional map

The map method applies a function to the contained value when it is present. The function returns an ordinary value, which Java wraps in a new Optional. An empty Optional remains empty.

Main.java
void main() {
 var word = Optional.of("falcon");
 var length = word.map(String::length);
 length.ifPresent(System.out::println);
}

Here, map changes an Optional<String> into an Optional<Integer> containing the length of the word.

Optional flatMap

The flatMap method applies the provided mapping function to a value if it is present. It returns that result or otherwise an empty Optional. If the result is already an Optional, flatMap does not wrap it within an additional Optional.

Main.java
void main() {
 Function<String, Optional<String>> upperCase = s -> Optional.of(s.toUpperCase());
 var words = Arrays.asList("rock", null, "mountain",
 null, "falcon", "sky");
 for (var value : words) {
 var word = Optional.ofNullable(value);
 var res = word.flatMap(upperCase);
 res.ifPresent(System.out::println);
 }
}

In this example, we apply the upperCase function on the list of words. flatMap returns the Optional from the function without creating an Optional<Optional<String>>.

JSoup example

In the following example, we use JSoup library to parse and modify an HTML document.

For the project, we need the jsoup artifact.

Main.java
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
void main() {
 String htmlString = """
 <html>
 <head>
 <title>My title</title>
 </head>
 <body>
 <main></main>
 </body>
 </html>
 """;
 var doc = Jsoup.parse(htmlString);
 var mainEl = Optional.ofNullable(doc.select("main").first());
 mainEl.ifPresent(e -> {
 e.append("<p>hello there!</p>");
 e.prepend("<h1>Heading</h1>");
 });
 System.out.println(doc);
}

We parse an HTML string and look for the main tag. If it is present, we append p and h1 tags to the document.

var doc = Jsoup.parse(htmlString);
Optional<Element> mainEl = Optional.ofNullable(doc.select("main").first());

The main tag might not be present and the first method in this case will return null. Therefore, we use the Optional.ofNullable method.

mainEl.ifPresent(e -> {
 e.append("<p>hello there!</p>");
 e.prepend("<h1>Heading</h1>");
});

We only call append and prepend methods if the Optional contains the main tag.

Jdbi example

The findOne method returns the only row in the result set, if any. It returns Optional.empty() if zero rows are returned, or if the row itself is null.

For the example, we need the jdbi3-core and the postgresql artifacts.

Main.java
import org.jdbi.v3.core.Jdbi;
void main() {
 var jdbcUrl = "jdbc:postgresql://localhost:5432/testdb";
 var user = "postgres";
 var password = "your-password";
 var jdbi = Jdbi.create(jdbcUrl, user, password);
 var id = 3;
 var query = "SELECT name FROM cars WHERE id = ?";
 var res = jdbi.withHandle(handle -> handle.select(query, id)
 .mapTo(String.class)
 .findOne());
 res.ifPresentOrElse(System.out::println, () -> System.out.println("N/A"));
}

In the example, we select a single cell from a row in a table. We print the data if it is present or N/A if not.

Source

Java Optional - language reference

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Java tutorials.

AltStyle によって変換されたページ (->オリジナル) /