Search

Dark theme | Light theme

March 24, 2021

Java Joy: Run Action When Optional Value Present Or Not

If we have an Optional instance we can consume the value if it is present using the ifPresent method. Since Java 9 the method ifPresentOrElse has been added to the Optional class. The first argument is of type Consumer and is invoked when there is an optional value. The second argument is of type Runnable and is executed when the the optional is empty. The method in the Consumer and Runnable implementations does not return a type but returns void. Therefore we should use ifPresentOrElse when we need a conditional side effect for an Optional instance.

In the following example we have a method handleName that will update a list if an optional value is present or increases a counter when the optional value is empty:

package mrhaki.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

public class IfPresentOrElse {

    // Store names.
    private static List<String> names = new ArrayList<>();
    
    // Counter for counting empty or null names.
    private static AtomicInteger emptyCounter = new AtomicInteger();

    public static void main(String[] args) {
        // Optional name property will have a value.
        handleName(new User("mrhaki"));

        assert "MRHAKI".equals(names.get(0));
        assert 0 == emptyCounter.get();
        
        // Reset properties
        names.clear();
        emptyCounter.set(0);
        
        // Optional name property is empty.
        handleName(new User());

        assert names.isEmpty();
        assert 1 == emptyCounter.get();
    }

    private static void handleName(User user) {
        user.getName().ifPresentOrElse(
                // If present add name in uppercase to names.
                s -> names.add(s.toUpperCase(Locale.ROOT)),
                // If not present increment the counter.
                emptyCounter::incrementAndGet);
    }

    // Simple class with an optional property name.
    private static class User {
        private final String name;

        private User() {
            this(null);
        }

        private User(final String name) {
            this.name = name;
        }

        Optional<String> getName() {
            return Optional.ofNullable(name);
        }
    }
}

Written with Java 16.